TypeScriptの網羅性チェック
下記に示しているのは自作の関数exhaustiveCheckを毎度呼ぶものだが、これの記述自体をなくせる
「「チェック漏れ」漏れ」をなくせる
Union型に対して網羅性チェックをする
以下のように書くと、例えばcase 'C'が抜けているときにエラーを出してくれる
code:ts
const hoge = (v: 'A' | 'B' | 'C') => {
switch (v) {
case 'A':
return;
case 'B':
return;
case 'C':
return;
default:
const _: never = v;
}
};
正しいときも'_' is declared but its value is never read.が出るので以下のような関数を用意しておくとよい
code:ts
export const exhaustiveCheck = (x: never): never => {
throw new Error(Unexpected object: ${x});
};
上のコードをこう書き換える
code:ts
default:
return exhaustiveCheck(v);
ヘルパー関数を使わない例
code:ts
throw new Error(Unknown type: ${(action as { type: "__invalid__" }).type});
code:ts
new Error(${action satisfies never})
ReduxのReducerで使用する場合
しかし、これをreduxのreducerのswitch文で同じようなことするとエラーになる
何故なら、自分で定義したAction型とは別に@@redux/INIT${randomString()}のようなActionが投げ込まれるため、実行時にdefault節に入り、Errorがthrowされる
exhaustiveCheck関数とは別に、reducer用の漏れチェック関数を用意すると良い
code:ts
export const endReducer = <T>(state: T, _action: never): T => {
return state;
};
code:ts
function reducer(...) ..
switch (action.type) {
...
default:
return endReducer(state, action);
}
}