generated at
TypeScriptの網羅性チェック


switch-exhaustiveness-checkを導入するのが良さそう
下記に示しているのは自作の関数 exhaustiveCheck を毎度呼ぶものだが、これの記述自体をなくせる
「「チェック漏れ」漏れ」をなくせる


Union型に対して網羅性チェックをする
以下のように書くと、例えば case 'C' が抜けているときにエラーを出してくれる
ts
const hoge = (v: 'A' | 'B' | 'C') => { switch (v) { case 'A': return; case 'B': return; case 'C': return; default: const _: never = v; } };
noUnusedLocals true にしている場合
正しいときも '_' is declared but its value is never read. が出るので以下のような関数を用意しておくとよい
ts
export const exhaustiveCheck = (x: never): never => { throw new Error(`Unexpected object: ${x}`); };
上のコードをこう書き換える
ts
default: return exhaustiveCheck(v);



ヘルパー関数を使わない例
ts
throw new Error(`Unknown type: ${(action as { type: "__invalid__" }).type}`);
ts
new Error(`${action satisfies never}`)



ReduxのReducerで使用する場合
しかし、これをreduxのreducerのswitch文で同じようなことするとエラーになる
何故なら、自分で定義したAction型とは別に @@redux/INIT${randomString()} のようなActionが投げ込まれるため、実行時にdefault節に入り、Errorがthrowされる
exhaustiveCheck関数とは別に、reducer用の漏れチェック関数を用意すると良い
ts
export const endReducer = <T>(state: T, _action: never): T => { return state; };
ts
function reducer(...) .. switch (action.type) { ... default: return endReducer(state, action); } }