株式会社学びと成長しくみデザイン研究所の藤澤です。
TypeScript において、「型で定義していない値が switch 文などに渡された際に、それをエラーとして検出する」という挙動を、例えば以下のように実装したとします。
type Element = 'rhythm' | 'melody' | 'harmony'
const element: Element = 'rhythm'
switch (element) {
case 'rhythm':
rhythmFunction()
break
case 'melody':
melodyFunction()
break
case 'harmony':
harmonyFunction()
break
default:
throw new Error(`不正な値: ${element}`)
}
このコードでは、switch に型 Element
で定義されていない値が来た場合にエラーを出してくれます。
しかしエラーのタイミングは実行時なので、例えば型 Element
に新しい値を追加した際、それに対応した実装を忘れていても実行時エラーが出るまで気が付かない可能性もあります。
なので、型に新しい値を追加した際などに、実行前に型エラーを出してもらえるように改修します。
type Element = 'rhythm' | 'melody' | 'harmony' | 'timbre' // 新しい値 'timbre' を追加
const element: Element = 'rhythm'
// 明示的に引数に値が入らないことが分かる関数を作成
const assertUnreachable = (element: never): never => {
throw new Error(`不正な値: ${element}`);
};
switch (element) {
case 'rhythm':
rhythmFunction()
break
case 'melody':
melodyFunction()
break
case 'harmony':
harmonyFunction()
break
default:
assertUnreachable(element)
}
関数 assertUnreachable
の引数の型は never
なので値が入らない想定ですが、このコード上では少なくとも timbre
がこの関数に到達する可能性があり、実行前にその点を型エラーとして教えてくれます。
念の為に実行時エラーを出す挙動も残しています。