今回はTypeScriptの型アサーション(Type Assertion)について紹介します。利用するTypeScriptのバージョンは4.3.5
です。
目次
型アサーション(Type Assertion)とは
TypeScriptにはコードの周辺情報や文脈をもとに変数の型を推論する型推論(Type Inference)と呼ばれる機能があります。
TypeScriptがよしなに型を推論してくれるため、すべての変数や引数に対して型の定義をする必要がありません。
型アサーション(Type Assertion)はTypeScriptによって推論された型を上書きする機能です。変数を任意の型へ書き換えたい場合に型アサーションを利用します。
型アサーションの具体例
型アサーションの定義はas 指定したい型
です。
たとえば以下のコードは型推論に頼るとコンパイルエラーになります。
interface Hoge {
fuga: number;
piyo: string;
}
let hoge = {}; // {}型に型推論される
hoge.fuga = 123; // Property 'fuga' does not exist on type '{}'
hoge.piyo = 'hello'; // Property 'piyo' does not exist on type '{}'
上記のコードに対して型アサーションを適用し、コンパイルエラーをなくしたものが以下になります。
interface Hoge {
fuga: number;
piyo: string;
}
let hoge = {} as Hoge; // Hoge型に型アサーションする
hoge.fuga = 123;
hoge.piyo = 'hello';
型アサーションのおかげで変数hoge
をHoge
型として扱えるようになったため、コンパイルエラーが解消されました。
なお、明らかに正しくない型へは型アサーションを利用しても変更できません。
let fuga: number = 'hello' as number
// Conversion of type 'string' to type 'number' may be a mistake
型アサーションの注意点
型アサーションは任意の型に上書きができるため、型安全性が保証されなくなります。
つまり、型アサーションによる型に問題があった場合、コンパイルエラーとして検知されず、実行時に初めて気が付くことになります。
以下では型アサーションを利用する際に注意するべき具体例について紹介します。
適切でない型に気がつけない
以下のコードはコンパイルエラーにならず、実行時に初めてエラーがわかります。
let piyo = 'hello'
let fuga = piyo as any
// toPrecision() は指定された精度の文字列を返すnumber型のメソッド
console.log(fuga.toPrecision())
// [ERR]: fuga.toPrecision is not a function
fuga.toPrecision()
を実行するためには変数fuga
はnumber型でなければいけません。
しかし型アサーションを利用して変数fuga
をany型へ変換すると、string型が代入されたことをコンパイル時に検知できなくなります。
オブジェクトのプロパティ忘れに気がつけない
型アサーションをオブジェクトの初期化に利用した場合、プロパティが足りなくてもコンパイルエラーになりません。
interface Hoge {
fuga: number;
piyo: string;
}
let hoge = {} as Hoge;
hoge.fuga = 123;
オブジェクトの初期化をするのであれば、型アサーションに頼るのではなく、以下のように型を明記するとよいです。
interface Hoge {
fuga: number;
piyo: string;
}
const hoge: Hoge = {
fuga: 123
}; // Property 'piyo' is missing in type '{ fuga: number; }' but required in type 'Hoge'
型アサーションの使いどころ
型アサーションは『とりあえずコンパイルエラーを解決したい』という場合で利用します。
たとえば、JavaScriptからTypeScriptへの移行時の型エラーを解決するケースが型アサーションの利用例の1つです。
型アサーションは任意の型へ強制的に変更できるためコンパイルエラーを解消する強力な機能ですが、型安全性が保証されなくなります。
ですので、型アサーションはやみくもに利用するものではなく、コンパイルエラーを解消するための応急処置的な立ち位置だと認識しておくとよいです。
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!