ウェブサイト検索

redux - switch文のケースを自分の関数に移したときにTypeScriptのエラーが出る?


私は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 文の return ケースをそれぞれ独自の関数に移動したいです:

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 のエラーがあります:

プロパティ 'index' は型 'action' に存在しません。プロパティ 'index' は型 '{ type: "do-something"; width: number; isLandscape: boolean; }' に存在しません。ts(2339)

TypeScript が switch 文によって action オブジェクトに index プロパティがあることを認識していないのが分かります。これを認識させる方法はありますか?

回答 #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 バリアントでのみ動作します。