【问题标题】:TypeScript errors when I move switch statement cases to own functions?将 switch 语句案例移动到自己的函数时出现 TypeScript 错误?
【发布时间】:2020-06-21 11:25:44
【问题描述】:

我正在使用带有 Redux 的 TypeScript。此代码工作正常:

export type action =
  | {
      type: "do-other-thing";
      name: string;
    }
  | {
      type: "do-something";
      index: number;
    };

function reducer(state: state = initState, action: action): state {
  switch (action.type) {
    case "do-something":
        if (action.index === 0) return state;
        // More logic
    case "do-other-thing":
        // More logic
    default:
        return state;
  }

但是我想将 switch 语句中的返回案例移动到它们自己的函数中:

function doSomething(state: state, action : action): state {
    if (action.index === 0) return state;
    // more logic
}

function reducer(state: state = initState, action: action): state {
  switch (action.type) {
    case "do-something":
        return doSomething(state, action);
    case "do-other-thing":
        // More logic
    default:
        return state;
  }

现在doSomething 函数出现 TypeScript 错误:

“操作”类型上不存在属性“索引”。属性“索引” 不存在于类型'{ type: "do-something";宽度:数字; isLandscape:布尔值; }'.ts(2339)

我可以看到 TypeScript 不知道由于 switch 语句,action 对象将具有 index 属性。有没有办法让它意识到这一点?

【问题讨论】:

  • Typescript 怎么可能知道?您在 switch 语句之外定义函数,Typescript 无法知道您使用该函数的唯一位置是在 case 块内。
  • 我知道我们需要明确定义 action 的类型,但为什么理想的 TypeScript 编译器可能不知道它何时只在一个地方使用?

标签: typescript redux


【解决方案1】:

因为您在doSomething 函数上将参数定义为action,这允许任何人在其他地方传递任何action。您很可能希望将其实际定义为更受限制的类型,如下所示:

type DoOtherThingAction = { type: "do-other-thing"; name: string; };
type DoSomeThingAction = { type: "do-something"; index: number; };
export type action = 
  | DoOtherThingAction
  | DoSomeThingAction;

然后:

function doSomething(state: state, action : DoSomeThingAction): state {
    if (action.index === 0) return state;
    // more logic
}

【讨论】:

    【解决方案2】:

    函数doSomething 不适用于所有动作,但对于具有index 属性的动作,我会拆分一些打字以便能够更清楚地键入需求:

    type A = {
          type: "do-other-thing";
          name: string;
        };
    type B = {
          type: "do-something";
          index: number;
        };
    type Action = A | B
    
    function doSomething(state: state, action: B): state {
        if (action.index === 0) return state;
        // more logic
    }
    

    现在doSomething 仅适用于您的Action 类型的变体B

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多