項目9 型アノテーションを型アサーションより優先的に使用する
TypeScriptには変数に代入する型の指定方法が2つある
code:ts
interface Person { name: string };
const alice: Person = { name: 'Alice' };
const bob = { name: 'Bob' } as Person;
型アノテーション:alice: Person
値が型に適合することを保証する
型アサーション:as Person
TypeScriptの型推論を実装者が後から型を上書きする
型アノテーション
一般的には型アノテーションを優先して利用する
TypeScriptによる型推論によって型エラーを検知できるため
型アサーションでは、型エラーが無視される
code:ts
const alice: Person = {};
// ~~~~~ Property 'name' is missing in type '{}' but required in type 'Person'
// プロパティ 'name' は型 '{}' にありませんが、型 'Person' では必須です。
const bob = {} as Person; // エラーなし
TypeScriptには、宣言された型を持つオブジェクトに余分なプロパティが含まれる場合にエラーとする余剰プロパティチェックという機能がある
型アノテーションを使った場合のみ有効
詳しくは項目11 余剰プロパティチェックと型チェックを区別する
code:ts
const alice: Person = {
name: 'Alice',
occupation: 'TypeScript developer'
// ~~~~~~~~~ Object literal may only specify known properties,
// and 'occupation' does not exist in type 'Person'
// オブジェクト リテラルは既知のプロパティのみ指定できます。
// 'occupation' は型 'Person' に存在しません。
};
const bob = {
name: 'Bob',
occupation: 'JavaScript developer'
} as Person; // エラーなし
hr.icon
アロー関数で型アノテーションを使う場合
アロー関数の戻り値に型アノテーションをつける
code:ts
const people = 'alice', 'bob', 'jan'.map(
(name): Person => ({name})
);
(name): Personのカッコが重要
nameの値を型推論させ、map内の関数の戻り値がPersonであることを指定
mapの結果を格納する変数に型アノテーションを指定することで、型チェックの恩恵を受けることも可能
code:ts
const people: Person[] = 'alice', 'bob', 'jan'.map(name => ({name}))
型アサーション
型アサーションを使うべきシーンは、値の型をTyepScirpt以上に、実装者が本当に把握しているときのみ
TypeScriptが把握し得ない、DOM要素の型など
DOMの型については項目75 DOMの型階層を理解する
code:ts
document.querySelector('#myButton')?.addEventListener('click', e => {
e.currentTarget
// ^? (property) Event.currentTarget: EventTarget | null
// #myButtonのcurrentTargetはbutton要素である
const button = e.currentTarget as HTMLButtonElement;
});
ある変数の型にnullが含まれているが、文脈上ありえない事を実装者が知っている場合は、非nullアサーションを使う
code:ts
const el = document.getElementById('foo')!;
// ^? const el: HTMLElement
⚠️値が非nullであることを保証できるときのみ使う。そうでない場合はnullチェックで回避
型アサーションの限界
型アサーションを使って型を変換できる場合は、それらが互いに「比較可能」なときのみ
AとBのインターセクションが空(never型)でない場合のみ(項目7 型を値の集合として考える)
ただ、抜け道としてunknown型にアサーションすることで回避できる
code:ts
const el = document.body as unknown as Person;
ジェネリック型を利用した型アサーションはアンチパターン
TypeScriptが型推論していないのに、している風の動きに見えるため
くわしくは項目51 不必要な型パラメーターを避ける
as const
型アサーションではなく、const文脈と呼ばれる
型をより正確にするためのもので、完全に安全
くわしくは項目24 型推論に文脈がどう使われるか理解する
#TypeScript