Redux操作类型的并集仍然允许未知类型

时间:2019-01-14 17:17:13

标签: typescript

我创建了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}); //没有错误`

打字稿可以吗?

1 个答案:

答案 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