| 組み込みガード |
|---|
| プリミティブを絞り込みます。string、number、boolean など。 | if (typeof x === 'string') x.toUpperCase() |
| クラスまたは構築可能なインスタンスに絞り込みます。 | if (e instanceof Error) e.message |
| プロパティが値に存在するかどうかで絞り込みます。 | if ('id' in obj) obj.id |
| 任意の値を配列に絞り込みます。ユニオンは配列のメンバーに絞り込まれます。 | if (Array.isArray(x)) x.map(f) |
| カスタムガード |
|---|
| 戻り値が引数を絞り込む述語関数です。 | function isUser(x): x is User { return !!x.id } |
| 述語は単一の型だけでなく、型のユニオンにも絞り込めます。 | function isKey(x): x is string | number |
| 交差型の述語は入力型を保ったまま、そこにフィールドを追加します。 | function hasId(x): x is x & { id: string } |
| x がその型でなければ例外を投げるアサーション関数です。 | function assertUser(x): asserts x is User |
| 判別可能なユニオン |
|---|
| switch や if で、共通のリテラルフィールドによってユニオンを絞り込みます。 | type E = { kind: 'a'; a: number } | { kind: 'b'; b: string } |
| 各 case はユニオンの 1 つのメンバーに絞り込みます。 | switch (u.kind) { case 'a': u.a } |
| プロパティが 1 つのメンバーにしか存在しない場合に、タグなしユニオンを絞り込みます。 | if ('b' in u) u.b |
| 各 case は条件式です。マッチした case が値を絞り込みます。 | switch (true) { case typeof x === 'string': } |
| default ケースで never に代入することで、switch が網羅的であることを証明します。 | default: { const x: never = u } |
| 等価性とフロー |
|---|
| 等価性のチェック後に null と undefined を除外します。 | if (x === null) return; x.toFixed() |
| falsy な値(0、''、null、undefined、NaN)を除外します。 | if (!x) return; // x is defined here |
| truthy な連鎖プロパティは、ベースとなる値が存在することを証明します。 | if (user?.active) user.name |
| 非 null アサーションはチェックなしで null と undefined を除外します。 | x!.toFixed(2) |
| definite assignment:x は読み取られる前に代入されると宣言します。 | let name!: string; init() |
| 絞り込みは分岐の中と早期 return の後にも適用されます。 | if (!arr) return; arr.map(...) |
| エイリアスと遅延 |
|---|
| チェックを保持する const boolean は、評価されるどこでも絞り込みます。 | const isStr = typeof x === 'string'; if (isStr) … |
| const 変数は、それをキャプチャするクロージャの中で絞り込みを保持します。 | const s = get(); if (s) use(() => s.length) |
| TS 5.4 以降、let や引数は最後の代入の後もクロージャ内で絞り込みを保持します。 | let n: string | null = get(); if (n) use(() => n.length) |
| unknown は、ガードが実際の型に絞り込むまで使用できません。 | if (typeof u === 'string') u.length |