-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Typescript typed vuex #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We may improve Vuex type declaration by using keyof and Mapped Types that is introduced on TS 2.1 |
I did some Typescript fiddles approaches, may not be the "perfect" solution unless some form of macroing is available, but seems pretty okay as you should get typehinting/checking right off the board given the necessary boilerplate. Typescript fiddles: http://tinyurl.com/hzp9ulv To avoid further boilerplate with re-defining union type per store.commit call, you can encapsulate via a higher-order domain-specific commit/dispatch helper method. eg,
Another altenative is to use HaxeVx. It has a Vuex implementation in Haxe, (but not production-ready yet, got working proof of concept based off Shopping Cart Vuex example) that strictly-types dispatches and commits' payloads fully, and does so without having to manage any strings or constants. For example, for a given Vue component class, all i need to do is call It leverages on the Haxe compiler and Macro features to ensure a fully static-typed (and customised) development experience for coding both VueJS and Vuex stuff. The A Design doc for HaxeVx, Vuex, can be found at: Another way for Typescript is to go down runtime Decorator approach, and heavily rely on them to construct something similar to what HaxeVx does. Mock examples: The idea is to have a decorated class instance payloaded function call that actually returns the handler at runtime initialization (even though the function is ret-typed to |
@yyx990803 @ktsn there is a way keep API compatible and type safety in vuex ? I try to refactor the declaration file. But Can't maintain the type-payload relationship (mutation -> commit, action -> dispatch), so |
👍 |
@ktsn , What do you think about mutation types interface like this? // mutation-types.ts
/**
* @type {{[mutationName]: payloadType}}
*/
export interface MutationTypes {
ROOT_INCREMENT: number;
ROOT_INCREMENT5: void;
MODULE_INCREMENT: number;
MODULE_INCREMENT2: void;
} It can be used if we change type of Store.commit method: // shims.d.ts
declare module 'vuex' {
import * as Vuex from '@/../node_modules/vuex';
export * from '@/../node_modules/vuex';
import { MutationTypes } from '@/mutation-types';
export class Store<S> extends Vuex.Store<S> {
// FIXME: payload is required
/** @override check payload type */
commit: <T extends keyof MutationTypes>
(type: T, payload: MutationTypes[T], options?: Vuex.CommitOptions) => void;
}
const DEFAULT: {
Store: typeof Store;
install: typeof Vuex.install;
};
export default DEFAULT;
} And now we can just use |
I try to solve problems with types at here https://github.com/justerest/vue-ts/tree/master/src |
Any movement on this? Is https://github.com/istrib/vuex-typescript what I should probably use if I want better typing in the near future when using vuex? |
@joevandyk I actually tried using vuex-typescript for my project, but it turned out to become more of a hassle than an improvement that often times made things more complex. One issue I remember having very clearly is that if you wanted, say, call an action of a different module from the action of your module, you still had to use the dispatch('action-name', { payload }), which is not typesafe, while calling actions within your own module you could just typesafely execute the method. I ended up using vuex-simple, which takes vuex all the way into Typescript by having Typescript modules be usable classes for whom the |
I tried to tackle it here - with no additional code, just better typing: https://github.com/ClickerMonkey/vuex-typescript-interface Not only can you pass a State type to the Store, but it detects getters, mutations, and actions and forces you to use those names and types defined in the interface passed in. |
Closing due to duplicated issue #564 (this one is newer and have more comments). |
Right now it's hard to maintain type safety with
Vuex
andTypescript
because of the way the$store
exposes actions and mutations through string-baseddispatch
andcommit
. At compile time there's no way to know the strings are valid or that the passed payload has the requisite fields.There's this valiant effort:
Though that API doesn't really look like the
Vuex
API to me. Would there be interest in trying to allow typescript type safety in Vuex? Are there existing best practices?The text was updated successfully, but these errors were encountered: