TypeScript 4.9でsatisfies
演算子が追加されて以降、もうこれなしのTypeScriptなんては考えられなくなってしまいました。様々な場面で便利なので、satisfies
演算子の使い道についてまとめてみます。
基本の使い方
satisfies
演算子は型推論の結果を失わずに型をチェックするために実装されました。
どういうことかというと、例えば、
こんな感じで配列からリテラル型のユニオンとしてColorName
型を得たいとします。しかし、これだとColorName
型は正しく得られるものの、以下のようなtypoに気づくことができません。
なので、colors
変数が正しいことを保証するために型注釈を追加してみますが、
これだとcolors
変数は正しいものの、型注釈によってwideningが発生し、ColorName
がstring
型になってしまいます。
そこで、
こんな感じでsatisfies
演算子を使ってあげることで、型推論の結果を活かしながらcolors
変数の型をチェックできます。もちろん、typoも検出できます。
より現実的な例としては、AstroでgetStaticPaths()
の型チェックのためにsatisfies
演算子が活用されていたりします。
別の使い方
型注釈は代入する時のみ利用できるのに対し、satisfies
演算子は代入を伴わずに式が返す値の型をチェックできます。
この特徴を利用して以下のような使い方も考えられます。
switch文の網羅性チェック(exhaustiveness check)をする
こんなコードがあったとします。
subject.type
が'History'
のときの処理を書き忘れているため、このコードを実行してもなにも表示されません。
しかし、以下のようにして型レベルで網羅性を保証してあげることができます。
もっとも、satisfies
演算子を使わずとも、デフォルトケースで
のようにしたり、never
型の引数を取る関数にsubject
を渡すことで網羅性チェックはできます。
しかし、前者の方法では_assert is declared but its value is never read.
のエラーが出てしまい、後者の方法ではわざわざアサート用の関数を用意しなければいけないという欠点があります。
それを考慮するとやはりsatisfies
を使って網羅性チェックをするのがキレイかなーと思っています。
最後に
改めてまとめてみたらあんまり使い道多くなかったですね。TypeScriptを書いているときは事あるごとにsatisfies
ってタイプしてはsatisfies
が使える現代に生まれたことを感謝していたつもりだったのですが、ただの気のせいだったようです。
もし他にも便利な用途を見つけたら追記するかもしれません。