Skip to content

Typenarrowing in TypeScript uitgelegd

De manieren waarop TypeScript een type vernauwt binnen een tak, gegroepeerd per techniek: ingebouwde guards, eigen predicaten, assertion-functies, discriminated unions, gelijkheid en truthiness-flow, en gealiaseerde en uitgestelde narrowing. Elke rij koppelt de techniek aan een voorbeeld van één regel.

Narrowing is hoe TypeScript een breed type omzet in een nauwer type binnen een codetak, zodat het kan bewijzen dat een property-toegang veilig is. Elke check (typeof, in, een predicaat, een discriminant) vertelt de compiler: vanaf hier is de waarde specifieker. De technieken hieronder zijn de werkset.

Referentietabel · 23 items
23 of 23 rows
Ingebouwde guards
Vernauwt primitieven: string, number, boolean en meer.if (typeof x === 'string') x.toUpperCase()
Vernauwt naar een instantie van een klasse of iets constructeerbaars.if (e instanceof Error) e.message
Vernauwt door te controleren of een property op de waarde bestaat.if ('id' in obj) obj.id
Vernauwt elke waarde naar een array; vernauwt een union naar zijn array-lid.if (Array.isArray(x)) x.map(f)
Eigen guards
Een predicaatfunctie waarvan de return het argument vernauwt.function isUser(x): x is User { return !!x.id }
Een predicaat kan vernauwen naar een unie van typen, niet alleen naar één.function isKey(x): x is string | number
Een intersectie-predicaat houdt het inputtype en voegt er velden aan toe.function hasId(x): x is x & { id: string }
Een assertion-functie die gooit tenzij x van het type is.function assertUser(x): asserts x is User
Discriminated unions
Vernauwt een unie op een gedeeld letterlijk veld, via switch of if.type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
Elke case vernauwt naar één lid van de unie.switch (u.kind) { case 'a': u.a }
Vernauwt een untagged unie wanneer een property op precies één lid bestaat.if ('b' in u) u.b
Elke case is een voorwaarde; de getroffen case vernauwt de waarde.switch (true) { case typeof x === 'string': }
De default-case wijst toe aan never en bewijst dat de switch volledig is.default: { const x: never = u }
Gelijkheid en flow
Verwijdert null en undefined na een gelijkheidscheck.if (x === null) return; x.toFixed()
Verwijdert falsy-waarden (0, '', null, undefined, NaN).if (!x) return; // x is defined here
Een truthy geketende property bewijst dat de basiswaarde aanwezig is.if (user?.active) user.name
Non-null assertion verwijdert null en undefined zonder check.x!.toFixed(2)
Definite assignment: verklaart dat x wordt toegekend voordat hij wordt gelezen.let name!: string; init()
Narrowing geldt binnen de tak en na vroege returns.if (!arr) return; arr.map(...)
Gealiaseerd en uitgesteld
Een const met een booleaanse waarde die een check vasthoudt, vernauwt overal waar hij wordt getest.const isStr = typeof x === 'string'; if (isStr) …
Een const-variabele houdt zijn narrowing binnen closures die hem vastleggen.const s = get(); if (s) use(() => s.length)
Sinds TS 5.4 houdt een let of parameter zijn narrowing in closures na zijn laatste toekenning.let n: string | null = get(); if (n) use(() => n.length)
unknown kan niet worden gebruikt tot een guard hem naar een echt type vernauwt.if (typeof u === 'string') u.length