如何正确地键入引用其他getter的vuex getter?例如:
import { GetterTree } from 'vuex';
class State {
foo: string[] = [];
}
const getters = <GetterTree<State, any>>{
bar: state => state.foo.filter(...something...),
baz: (state, getters) => getters.bar.filter(...something else...)
}
这里,由getters
定义将getters.baz
的any
参数键入为any
。如果可以根据{ bar: string[] }
声明隐式地将其键入为const getters
,而不必将其声明两次为接口之类的,那就太好了。有办法吗?
发布于 2021-08-31 01:30:10
让我们来看看GetterTree
接口:
export interface GetterTree<S, R> {
[key: string]: Getter<S, R>;
}
因此,state => state.foo.filter(...something...)
对应于Getter<S, R>
。
不幸的是,第二个参数getters
不是泛型的,默认情况下输入为any
。
export type Getter<S, R> = (state: S, getters: any, rootState: R, rootGetters: any) => any;
来自R
的泛型参数GetterTree
对应于rootState
,我们对此并不感兴趣。
我有两种选择。
优先--最简单的.
只需向第二个参数添加显式类型:
const getters: GetterTree<State, any> = {
bar: state => state.foo.filter(e => e.length > 1),
baz: (state, getters: { bar: string[] }) => getters.bar
}
第二种方法是覆盖构建在实用程序类型中的GetterTree
。
import { GetterTree, Getter } from 'vuex';
class State {
foo: string[] = [];
}
type CustomGetter<T extends Getter<any, any>, Getters> =
T extends (state: infer State, getters: infer _, rootState: infer RootState, rootGetters: infer RootGetters) => any
? (state: State, getters: Getters, rootState: RootState, rootGetters: RootGetters) => any
: never
type CustomGetterTree<T extends GetterTree<any, any>, Getters> = T extends GetterTree<infer S, infer R> ? {
[key: string]: CustomGetter<Getter<S, R>, Getters>;
} : never
const getters: CustomGetterTree<GetterTree<State, any>, { bar: string[] }> = {
bar: state => state.foo.filter(e => e.length > 1),
baz: (state, getters /** { bar: string[];} */) => getters.bar
}
发布于 2022-06-18 09:24:01
编辑:,如果在Vuex中使用Vue3和TypeScript,我会切换到皮皮亚,它似乎具有良好的类型安全性。至少为我工作过。
不知道是否值得考虑另一种方法。我喜欢尝试使用帮助函数推断getter的返回类型。我发现它节省了复杂类型的定义,尽管它会在引用getter的键上引起一些重复。
const getters = {
gridHeight(): number {
return 32;
},
message(): string {
return 'hello ';
},
};
const store = createStore<State>({ getters });
type ReturnOfGetter<T> = T extends (state: infer _, getters: infer _, rootState: infer _, rootGetters: infer _) => infer Return
? Return
: never;
export function useGetter<K extends keyof typeof getters>(key: K): ReturnOfGetter<typeof getters[K]> {
return store.getters[key];
};
这允许这样的访问:
const gridHeight = useGetter<'gridHeight'>('gridHeight');
const message = useGetter<'message'>('message');
https://stackoverflow.com/questions/68995690
复制