我创建了this ts playground来显示问题。
我有这种类型:
export type ApiActionCreator<T extends object, Payload = object | any[] | undefined> = T & { payload: Payload, error: ErrorMessage }
我想用来创建redux动作类型,例如:
export enum RoleActionTypes {
GET_ALL = '@@role/GET_ALL',
GET_ALL_OK = '@@role/GET_ALL_OK',
GET_ALL_FAIL = '@@role/GET_ALL_FAIL'
}
export type GetAll = ApiActionCreator<{ type: RoleActionTypes.GET_ALL }>;
export type GetAllOK = ApiActionCreator<{ type: RoleActionTypes.GET_ALL_OK }, Role[]>;
export type GetAllFail = ApiActionCreator<{ type: RoleActionTypes.GET_ALL_FAIL}>;
export type RoleActionCreators =
GetAll
| GetAllOK
| GetAllFail;
然后我将其用作我的reducer的参数:
export const roles: Reducer<RoleState> = (state = defaultRoleState, action: RoleActionCreators) => {
switch (action.type) {
case RoleActionTypes.GET_ALL:
它将为未知的case switch语句引发编译时错误,但仍然可以使用未知的操作类型调用reducer:
recducer(undefined, {type: 'DO_SOMETHING
}); //没有错误`
打字稿可以吗?
答案 0 :(得分:0)
问题确实非常简单,Reducer
有第二个类型参数来表示操作的类型。由于您没有在变量类型注释中指定它,因此第二个参数的类型将不会保留在roles
函数中,并且将默认为AnyAction
这将触发预期的错误:
export const roles: Reducer<RoleState, RoleActionCreators> = (state = defaultRoleState, action) => {
switch (action.type) {
case RoleActionTypes.GET_ALL:
default:
return state;
}
}
roles(undefined, { type: 'DO_SOMETHING' }); // err