TypeScriptの型アノテーションと型アサーション。どちらも名前が似ているし、変数の型情報を何やら操作するという点でも似ています。
混同を避けて正しく使用するためにも、両者の違いと注意点について整理してみました。
間違った点があれば指摘していただけると幸いです。
型アノテーション
「型推論を明示的に行う」
型推論とは、変数宣言時にコンパイラが文脈を読み取って自動的に型を推論してくれる機能のことである。
型アノテーションは、コンパイラの自動的な型推論に全て任せるのではなく、開発者が任意の型を指定して明示的に型推論を行うことである。
コンパイラに対して「この変数に代入できる型はこの型だよ」と伝えるようなイメージです。
したがって、型アノテーション後はコンパイラが変数代入時に指定した型の値かどうかを照合して、代入できない時はエラーを返してくれるようになる。
型アノテーションは、変数、定数、関数、引数の後ろに「: 型名」を記述することで明示的に型を指定することができる。
let age: number; // 型アノテーション
age = 18; // OK
age = "John"; // Error
型アサーション
「型推論された型情報の上書きを明示的に行う」
型アノテーションと異なるのは、「コンパイラによって型推論された変数の型情報を上書きする」という点。
これは、コンパイラに対して「型推論ではこの型だったけど、本当はこっちの型です。」と伝えるようなイメージです。
型アサーションは値の前に「<型名>」を記述するアングルブラケット構文と、値の後ろに「as 型名」を記述するas方法の2種類がある。
(ちなみに、Reactで使用されるJSX構文との混合を避けるために「as構文」の書き方が推奨されている。)
interface Person { age: number };
let john = {} as Person; // 型アサーション
let bob = {};
john.age = 18; // No Error
bob.age = 17; // Error(Property 'age' does not exist on type '{}')
型アサーションの注意点
型アサーションを用いる際の注意点は、コンパイルエラーに気がつけない可能性があること。
型アサーションの大きな特徴は、「コンパイラによって型推論された変数の型情報を強制的に上書きする」ということ。
つまり、コンパイラによる型推論を上書きすると、間違った型の値を代入してもコンパイラがエラーを検出してくれないようになります。
(一方で、型アノテーションの場合は、コンパイラによる型推論を開発者が明示的に指定するため、間違った型の値を代入した際にはコンパイラがエラーを報告してくれる。)
例えば、以下のようにオブジェクトを初期化する場合、型アサーションを用いる時はその型に必要なプロパティを全て満たしていなくてもコンパイラはエラーを返してくれません。
interface Person {
name: string;
age: number;
}
// 型アノテーション(Error: Type '{}' is missing the following properties from type 'Person': name, age)
const john: Person = {};
// 型アサーション(No Error)
const bob = {} as Person;
オブジェクトが余分なプロパティを持っている時も同様に、型アサーションを用いた時はコンパイラはエラーを返しません。
interface Person {
name: string;
age: number;
}
// 型アノテーション(Error: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.)
const john: Person = {
name: 'john',
age: 18,
gender: 'male',
};
// 型アサーション(No Error)
const bob = {
name: 'bob',
age: 17,
gender: 'male',
} as Person;
以上のように、型アサーションを用いるとエラーやバグに気づかずにプログラムを実行してしまう可能性があります。
そのため、開発者がコンパイラよりもその変数の型に詳しい・確証がある場合でなければ、型アサーションの使用を避けて型アノテーションで型推論を明示的に指定するのが良いと思います。
まとめ
「型推論を明示的に行う」のが型アノテーション
「型推論された型情報を上書きする」のが型アサーション
型アサーションは、コンパイラによる型推論を強制的に上書きするので間違った型の値を代入してもコンパイラがエラーを検出してくれない(=開発者自身で間違っているかどうか判別する必要がある)。
エラーやバグを事前に防ぐためにも、型情報に詳しい・確証がある場合は型アサーション、それ以外の何か特別な理由がなければ型アノテーションを使用する。
参考サイト
- 型アサーション「as」(type assertion)
- 型宣言と型アサーション