对接收动作类型的 TypeScript reducer 进行类型检查

Posted

技术标签:

【中文标题】对接收动作类型的 TypeScript reducer 进行类型检查【英文标题】:Type-checking a TypeScript reducer receiving action types 【发布时间】:2019-12-26 23:05:39 【问题描述】:

我正在尝试创建一个接受 actionType 作为键值的 TypeScript redux reducer,但是我正在努力为我的状态定义正确的接口。这样做时,我收到以下消息:

TS7053:元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引“SampleState”类型。在“SampleState”类型上找不到带有“字符串”类型参数的索引签名。

当我的 reducer 接收到 actionType 时,如何正确地检查它的类型?谢谢,你可以看到下面的示例代码。

sampleActionTypes.ts:

export const FOO = 'FOO';
export const BAR = 'BAR';
export const TURN_ON = 'TURN_ON';
export const TURN_OFF = 'TURN_OFF';

interface TurnOn 
  type: typeof TURN_ON;
  actionType: string;


interface TurnOff 
  type: typeof TURN_OFF;
  actionType: string;


export type Types = TurnOn | TurnOff;

sampleReducer.ts:

import  BAR, FOO, TURN_OFF, TURN_ON, Types  from './sampleActionTypes';

export interface SampleState 
  [FOO]: 
    toggle: boolean;
  ;
  [BAR]: 
    toggle: boolean;
  ;


const initialState: SampleState = 
  [FOO]: 
    toggle: false,
  ,
  [BAR]: 
    toggle: false,
  ,
;

const sampleReducer = (state = initialState, action: Types): SampleState => 
  switch (action.type) 
    case TURN_ON:
      return 
        ...state,
        [action.actionType]: 
          ...state[action.actionType],
          toggle: true,
        ,
      ;
    case TURN_OFF:
      return 
        ...state,
        [action.actionType]: 
          ...state[action.actionType],
          toggle: false,
        ,
      ;
    default:
      return state;
  
;

export default sampleReducer;

【问题讨论】:

【参考方案1】:

您的状态在您的SampleState 接口之后具有FOO | BAR 作为键。 而你的Types['actionType']string

所以当你在做state[action.actionType] 时,你在做SampleState[string]。但是SampleState 只接受FOOBAR

根据您的需要,一个解决方案可能是输入Types['actionType']: (typeof FOO) | (typeof BAR)(类似的东西)。

还要注意如何命名字段。也许这只是为了举例,但是actionType 当动作界面中已经有一个type 时,这似乎是多余的并且相当混乱。

【讨论】:

【参考方案2】:

SampleState 接口更新为以下解决了这个问题:

export interface SampleState 
  [key: string]: 
    toggle: boolean;
  ;

【讨论】:

以上是关于对接收动作类型的 TypeScript reducer 进行类型检查的主要内容,如果未能解决你的问题,请参考以下文章

Typescript - 确保泛型属性存在于具有描述性错误的泛型类型上

Redux - reducer 与动作的关系

如何使用 redux-toolkit 中的 createSlice 方法在不同的 reducer 函数中使用单个动作类型

Thunk 动作创建者派出另一个 thunk 动作创建者,但 typescript 抛出错误。我应该添加啥类型?

在 redux-observable 中,我如何控制 reducer 或 epics 是不是首先对动作做出反应?

TypeScript - 使用只有可选字段的返回类型减少 [关闭]