| Guard ในตัว |
|---|
| จำกัด primitive ให้แคบลง: string, number, boolean และอื่น ๆ | if (typeof x === 'string') x.toUpperCase() |
| แคบลงเป็น instance ของคลาสหรือสิ่งที่ construct ได้ | if (e instanceof Error) e.message |
| แคบลงโดยตรวจว่ามี property นั้นอยู่บนค่า | if ('id' in obj) obj.id |
| แคบค่าใด ๆ ให้เป็น array; แคบ union ให้เหลือสมาชิกที่เป็น array | if (Array.isArray(x)) x.map(f) |
| Guard ที่เขียนเอง |
|---|
| ฟังก์ชัน predicate ที่ค่าตอบกลับทำให้อาร์กิวเมนต์แคบลง | function isUser(x): x is User { return !!x.id } |
| predicate แคบลงเป็น union ของหลายชนิดได้ ไม่ใช่ชนิดเดียวเท่านั้น | function isKey(x): x is string | number |
| predicate แบบ intersection เก็บชนิดตั้งต้นไว้แล้วเพิ่มฟิลด์เข้าไป | function hasId(x): x is x & { id: string } |
| assertion function ที่โยน exception เมื่อ x ไม่ใช่ชนิดนั้น | function assertUser(x): asserts x is User |
| Union แบบแยกด้วยแท็ก |
|---|
| แคบ union ด้วยฟิลด์ literal ที่ทุกสมาชิกมีร่วมกัน ผ่าน switch หรือ if | type E = { kind: 'a'; a: number } | { kind: 'b'; b: string } |
| แต่ละ case แคบลงเหลือสมาชิกหนึ่งตัวของ union | switch (u.kind) { case 'a': u.a } |
| แคบ union ที่ไม่มีแท็ก เมื่อ property มีอยู่บนสมาชิกเดียวเท่านั้น | 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 |
| property ที่ทอดสายแล้วเป็น truthy พิสูจน์ว่าค่าตั้งต้นมีอยู่จริง | if (user?.active) user.name |
| non-null assertion ตัด null และ undefined ออกโดยไม่ตรวจ | x!.toFixed(2) |
| definite assignment: ประกาศว่า x ถูกกำหนดค่าก่อนถูกอ่าน | let name!: string; init() |
| การแคบลงมีผลภายใน branch และหลัง return ก่อนเวลา | if (!arr) return; arr.map(...) |
| นามแฝง & การเลื่อนเวลา |
|---|
| const boolean ที่เก็บผลตรวจไว้ จะแคบค่าทุกที่ที่มันถูกทดสอบ | const isStr = typeof x === 'string'; if (isStr) … |
| ตัวแปร const รักษาการแคบลงไว้ภายใน closure ที่จับมันไว้ | const s = get(); if (s) use(() => s.length) |
| ตั้งแต่ TS 5.4, let หรือพารามิเตอร์รักษาการแคบลงใน closure หลังการกำหนดค่าครั้งสุดท้าย | let n: string | null = get(); if (n) use(() => n.length) |
| unknown ใช้งานไม่ได้จนกว่า guard จะแคบมันลงเป็นชนิดจริง | if (typeof u === 'string') u.length |