Skip to content

Typ-Eingrenzung in TypeScript erklärt

Die Wege, wie TypeScript einen Typ innerhalb einer Verzweigung eingrenzt, gruppiert nach Technik: eingebaute Wächter, eigene Prädikate, Assertions-Funktionen, diskriminierte Unions, Gleichheit und Truthiness im Ablauf sowie Aliase und verzögerte Eingrenzung. Jede Zeile verbindet die Technik mit einem einzeiligen Beispiel.

Eingrenzung (Narrowing) ist, wie TypeScript einen weiten Typ innerhalb eines Codezweigs in einen engeren verwandelt, damit es den sicheren Zugriff auf eine Eigenschaft beweisen kann. Jede Prüfung (typeof, in, ein Prädikat, eine Diskriminante) sagt dem Compiler: ab hier ist der Wert spezifischer. Die Techniken unten sind das Arbeitsrepertoire.

Nachschlagetabelle · 23 Einträge
23 of 23 rows
Eingebaute Wächter
Grenzt Primitive ein: string, number, boolean und weitere.if (typeof x === 'string') x.toUpperCase()
Grenzt auf eine Instanz einer Klasse oder eines konstruierbaren Typs ein.if (e instanceof Error) e.message
Grenzt ein, indem geprüft wird, ob eine Eigenschaft auf dem Wert existiert.if ('id' in obj) obj.id
Grenzt jeden Wert auf ein Array ein; grenzt eine Union auf ihr Array-Mitglied ein.if (Array.isArray(x)) x.map(f)
Eigene Wächter
Eine Prädikatsfunktion, deren Rückgabewert das Argument eingrenzt.function isUser(x): x is User { return !!x.id }
Ein Prädikat kann auf eine Union von Typen eingrenzen, nicht nur auf einen einzelnen.function isKey(x): x is string | number
Ein Schnittmengen-Prädikat behält den Eingabetyp und fügt Felder hinzu.function hasId(x): x is x & { id: string }
Eine Assertions-Funktion, die wirft, wenn x nicht dem Typ entspricht.function assertUser(x): asserts x is User
Diskriminierte Unions
Grenzt eine Union über ein gemeinsames Literalfeld per switch oder if ein.type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
Jeder case grenzt auf ein Mitglied der Union ein.switch (u.kind) { case 'a': u.a }
Grenzt eine unmarkierte Union ein, wenn eine Eigenschaft nur auf einem Mitglied existiert.if ('b' in u) u.b
Jeder case ist eine Bedingung; der zutreffende case grenzt den Wert ein.switch (true) { case typeof x === 'string': }
Der default-Fall weist an never zu und beweist damit, dass der switch erschöpfend ist.default: { const x: never = u }
Gleichheit und Ablauf
Entfernt null und undefined nach einer Gleichheitsprüfung.if (x === null) return; x.toFixed()
Entfernt falsy-Werte (0, '', null, undefined, NaN).if (!x) return; // x is defined here
Eine truthy verkettete Eigenschaft beweist, dass der Basiswert vorhanden ist.if (user?.active) user.name
Die Non-Null-Assertion entfernt null und undefined ohne Prüfung.x!.toFixed(2)
Definite Assignment: deklariert, dass x zugewiesen ist, bevor es gelesen wird.let name!: string; init()
Eingrenzung gilt innerhalb der Verzweigung und nach frühen Returns.if (!arr) return; arr.map(...)
Aliase und verzögerte Eingrenzung
Ein const-Boolean mit einer Prüfung grenzt überall ein, wo er getestet wird.const isStr = typeof x === 'string'; if (isStr) …
Eine const-Variable behält ihre Eingrenzung in Closures, die sie einfangen.const s = get(); if (s) use(() => s.length)
Seit TS 5.4 behält ein let oder Parameter die Eingrenzung in Closures nach seiner letzten Zuweisung.let n: string | null = get(); if (n) use(() => n.length)
unknown kann nicht verwendet werden, bis ein Wächter es auf einen echten Typ eingrenzt.if (typeof u === 'string') u.length