![](/img/trans.png)
[英]Why is the generic type parameter T “unknown” in the return type? How can I type this function so that the return type is correctly inferred?
[英]Why can't these generic type be inferred?
我正在为 Vue 3 编写一个 Vuex 商店,最近以下问题一直困扰着我。
请考虑以下最小的可重现示例:
interface Options<State, G extends Getters<State>> {
state: State
getters: G,
mutations: {
[P: string]: (state: State, getters: G) => void
}
}
interface Getters<State> {
[P: string]: (state: State) => any
}
function createStore<State>(options: Options<State, Getters<State>>) {
return options
}
createStore({
state: {
count: 0
},
getters: {
isOdd: (state) => state.count % 2 === 1
},
mutations: {
incrementIfOdd (state, getters) {
if (getters.isOdd) {
// ^ a this cannot be inferred to Boolean here.
++state.count
// ^ ok, it is number.[enter image description here][1]
}
}
}
})
更多代码信息可以在这里找到: https://github.com/js-cosmos/vuex-light/issues/11
感谢您的帮助:D。
我尝试删除包装选项并且它有效!
为了简化示例代码:
// This works function spreadOptionsFn< State extends Record<any, any>, Getters extends Record<any, ({ state }: { state: State }) => any>, Mutations extends Record<any, ({ state, getters }: { state: State; getters: Getters }) => any> >(state: State, getters: Getters, mutations: Mutations) {} spreadOptionsFn( { stateKey: 'state' }, { getterKey: ({ state }) => state.stateKey }, { mutationKey: ({ state, getters }) => [state.stateKey, getters.getterKey] }, ) // But not this function wrappedOptionsFn< State extends Record<any, any>, Getters extends Record<any, ({ state }: { state: State }) => any>, Mutations extends Record<any, ({ state, getters }: { state: State; getters: Getters }) => any> >({ state, getters, mutations }: { state: State; getters: Getters; mutations: Mutations }) {} wrappedOptionsFn({ state: { stateKey: 'state' }, getters: { getterKey: ({ state }) => state.stateKey }, mutations: { mutationKey: ({ state, getters }) => [state.stateKey, getters.getterKey] }, })
更新 2:
我又错过了一些东西,最后用以下代码修复:
interface Options<
State extends Record<any, any>,
GetterKeys extends string,
MutationKeys extends string,
> {
state: State,
getters: {
[P in GetterKeys]: ({ state }: { state: State }) => any
},
mutations: {
[P in MutationKeys]: ({ state, getters }: { state: State; getters: {
[P in GetterKeys]: ({ state }: { state: State }) => any
} }) => any
},
}
function wrappedOptionsFn<
State extends Record<any, any>,
GetterKeys extends string,
MutationKeys extends string,
>(options: Options<State, GetterKeys, MutationKeys>) {
}
wrappedOptionsFn({
state: { stateKey: 'state' },
getters: { getterKey: ({ state }) => state.stateKey },
mutations: { mutationKey: ({ state, getters }) => [state.stateKey, getters.getterKey] },
})
这是因为您使用 P: 字符串作为突变和吸气剂,所以我们不知道具体的键是什么,因此可以推断出它们的类型。
您应该在这里为 P 使用额外的通用参数 - 对于 MutationKeys 和 GetterKeys,然后可以正确推断:
interface Options<
State,
MutationKeys extends string,
G extends Getters<State, string>
> {
state: State;
getters: G;
mutations: {
[P in MutationKeys]: (state: State, getters: G) => void;
};
}
type Getters<State, Keys extends string> = {
[key in Keys]: (state: State) => any;
};
function createStore<
State,
MutationKeys extends string,
GetterKeys extends string
>(options: Options<State, MutationKeys, Getters<State, GetterKeys>>) {
return options;
}
createStore({
state: {
count: 0
},
getters: {
isOdd: (state) => state.count % 2 === 1
},
mutations: {
incrementIfOdd(state, getters) {
if (getters.isOdd(state)) {
++state.count;
}
}
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.