我正在尝试为类似redux的reducer建立类型。但是使用打字稿枚举作为映射接口的索引存在一个奇怪的问题。
// possible action types
enum ActionType {
UpdateInterval,
None,
Test
}
// mapping interface [action-type]: data-type
interface ActionData {
[ActionType.UpdateInterval]: Interval;
[ActionType.None]: undefined,
[ActionType.Test]: number;
}
// wrapper for type&data
interface Action<T extends ActionType> {
type: T;
data: ActionData[T]
}
// reduce function type
type ReduceMap<S extends State> = { [key in ActionType]: (state: S, data: ActionData[key]) => S };
// reduce process map (I prefer using object instead of switch)
const reduceMap : ReduceMap<State> = {
[ActionType.UpdateInterval]: (state, data) => state,
[ActionType.None]: (state, data) => state,
[ActionType.Test]: (state, data) => state
};
// just reducer function
function reducer<T extends ActionType>(state: State, action: Action<T>) : State {
return reduceMap[action.type](state, action.data);
}
问题出在reducer函数内部:打字稿说第二个reduceMap函数参数的类型为never
。
但我希望它类似于Interval | undefined | number
。
Argument of type 'ActionData[T]' is not assignable to parameter of type 'never'.
Type 'number | Interval | undefined' is not assignable to type 'never'.
Type 'undefined' is not assignable to type 'never'.ts(2345)
我想从key
(在ReduceMap
类型)的ActionData接口获取数据类型时,会出现问题。但是我不知道如何解决它。