-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Feature: Manually install vuex/types/vue.d.ts
#994
Comments
I agree that we should manually declare |
This would be a huge boost in productivity for us Typescript users - current examples are extremely verbose, especially when it comes to writing getters. In order to get static typing on any namespaced property from the $store, you have to write a getter and a storeAccessor (provided by
Being able to specify the structure for this.$store on a per-project basis would save so many hours of work, I would like to pick this up if it's agreed that it would be the right direction. |
I think this is a good idea, my only concern is backwards compatibility since we just released a new major version. Is there anyway to tell TS not to use the included types? |
As far as I can see no, looks like it'll be a complete breaking change. If doing that we may aswell plan to improve typing layer where we can. @ktsn has done some awesome work over here. |
+1 for this. I came here to start the same discussion. We currently solve this by manually type casting
|
I will move this to a discussion thread, as there is more we can do to make the Vuex API more type friendly. |
Sounds good. Will the discussion remain here, or can you give us a link to it? |
I will add a link, forming the thread atm including details on current issues. |
@ktsn Has done some great work in getting Vuex more type safe. Thus this issue can be solved with his work, as we can do a major semver upgrade |
What is the state on adding this to the library? |
tsconfig.json {
"file": [
"./node_modules/vue-router/types/vue.d.ts",
"./node_modules/vuex/types/vue.d.ts",
],
"include": [
"./src/**/*",
],
} I have always import the description file manually. I actually prefer to use import. I may have multiple entry files, multiple vuex instances.
Change the type as you like
|
Any plans on this? |
@therealmikz I think that the only way to patch this at this moment is to use https://www.npmjs.com/package/patch-package It's not the best solution I know, but at least it works and makes your store state typed until it's officially solved. |
@michalsnik thanks, I've seen this one before and I was planning to check it out Edit: it worked. It's definitely not an elegant solution, but it does the job |
what's the recommended solution to allow for |
I would suggest going with a new, custom field that returns Object.defineProperty(Vue.prototype, "$stock", {
get(): Store<RootState> {
return this.$store;
}
});
declare module "vue/types/vue" {
interface Vue {
$stock: Store<RootState>;
}
} Now, all you need to do is to replace usage of |
This issue has been solved at the |
Checkout this article Vuex + TypeScript. |
If a workaround is still valuable (for those locked to a Vue2 codebase, for example), I found the following to be useful. It wraps the Vuex' builtin import { mapState } from "vuex";
export function mapTypedState<State>(keys: (string & keyof State)[]) {
type Key = typeof keys[number];
return mapState(keys) as {
[key in Key]: () => State[key];
};
} In your store definition you can create a type-specific call like this if you want... export function mapRootState(keys: (keyof RootState)[]) {
return mapTypedState<RootState>(keys);
} This can very tersely, and type-safely, construct locally mapped properties from the store's state. Note Vuex mapState calls can be namespaced if you want to pick out typed state from within a module. The code example below constrains the type of import { mapRootState } from "@/store";
import Vue from "vue";
export default Vue.extend({
name: "HelloWorld",
computed: {
...mapRootState(["message"]),
backwardsMessage(): string {
const chars = this.message.split("");
chars.reverse();
return chars.join("");
},
},
}); |
This is a breaking change
What problem does this feature solve?
With module merging in TS, we can override module interfaces. However it is limited, in the case of the Vuex types it's impossible to compose full typing layer in components.
If we make it optional to install
vuex/types/vue.d.ts
then we can do our own manual declaration. Which will enable fully typed structures. I would also rename tovuex/types/install.d.ts
What does the proposed API look like?
Once we allow custom installation we can do something similar to this to enable full typing layer.
The text was updated successfully, but these errors were encountered: