我试图在RTK中创建一个reducer,它接受两个共享泛型类型的参数。然而,似乎不可能在reducer
和prepare
函数之间共享泛型类型。
这里有一个我正在努力实现的例子
type SetPayload<T> = {
thingToBeSet: MyClass<T>;
value: T;
}
export const mySlice = createSlice({
name: 'mySlice',
initialState,
reducers: {
myReducer: {
reducer: (state, action: PayloadAction<SetPayload<any>>) => {
// Modify state here
},
prepare: <T>(thingToBeSet: MyClass<T>, value: T) => {
return {
payload: { thingToBeSet, value }
}
}
}
}
});
如上面的代码所示,我的prepare
函数使用了一个泛型参数(因为thingToBeSet上某些属性的类型必须与value的类型匹配)。然而,这个类型参数不能用于reducer函数中的action
类型-我尝试将其设置为any
,这给出了以下错误:
The types of 'payload.thingToBeSet' are incompatible between these types.
Type 'MyClass<never>' is not assignable to type 'MyClass<any>'.
Type 'any' is not assignable to type 'never'
由于any
不能转换为T
-但是我如何在reducer和prepare函数之间共享T
呢?
我想我想要的是以某种方式为myReducer对象创建一个通用的对象字面量,类似于这样(不幸的是不是有效的TS -这可能吗?):
myReducer: <T> {
reducer: (state, action: PayloadAction<SetPayload<T>>) => {
// Modify state here
},
prepare: (thingToBeSet: MyClass<T>, value: T) => {
return {
payload: { thingToBeSet, value }
}
}
}
任何帮助将不胜感激。
2条答案
按热度按时间6tdlim6h1#
不幸的是,这是不可能的。这些类型在内部被Map以创建一个新的动作创建器函数-并且被Map的类型不能继承泛型功能。
最好的办法是在导出动作生成器之前将其强制转换为泛型函数类型。
py49o6xq2#
我使用的最终解决方案是在createSlice之外手动创建action,并为reducer使用extraReducers属性。设置函数的
type
属性允许自动键入和类似于RTK的用法。这是更详细和不理想的,但它至少给出了正确的类型,并在reducer中的隐式类型。行动:
减速器: