Menu

TypeScript Utility Types: die vollständige Liste mit Beispielen

Jeder eingebaute Utility Type von TypeScript an einem Ort: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, die String-Typen und mehr, jeweils mit einer Beschreibung in einem Satz und einem ausführbaren Beispiel.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Utility Types sind in TypeScript eingebaute generische Typen, die einen Typ in einen anderen verwandeln. Statt einen zweiten User-Typ mit lauter optionalen Feldern zu schreiben, schreibst du Partial<User>; statt drei Felder zu kopieren, Pick<User, "id" | "name">. Sie sind global, ein Import ist also nicht nötig.

Wenn sich User ändert, ziehen alle vier abgeleiteten Typen mit. Die Standardbibliothek von TypeScript (lib.es5.d.ts) deklariert 22 Utility Types. Die folgenden Abschnitte listen alle auf, gruppiert nach der Art von Typ, mit der sie arbeiten, und mit einem Link zur ausführlichen Seite, wo es eine gibt.

Objekttypen: Partial, Required, Readonly, Pick, Omit, Record

Utility TypeWas er machtBeispiel
Partial<T>macht jede Eigenschaft optionalPartial<User> für die Daten eines Updates
Required<T>macht jede Eigenschaft verpflichtend (entfernt ?)Required<Config>, nachdem Standardwerte angewendet wurden
Readonly<T>macht jede Eigenschaft readonlyReadonly<State>
Pick<T, K>behält nur die Schlüssel KPick<User, "id" | "name">
Omit<T, K>entfernt die Schlüssel KOmit<User, "password">
Record<K, V>ein Objekttyp mit Schlüsseln K und Werten VRecord<"en" | "de", string>

Required<T> ist das Gegenteil von Partial<T>; die Partial-Seite behandelt beide, auch das explizite undefined, das ein Spread wie dieser durchlässt.

Union-Typen: Exclude, Extract, NonNullable

Utility TypeWas er machtBeispiel
Exclude<U, M>entfernt Union-Mitglieder, die an M zuweisbar sindExclude<"a" | "b" | "c", "a"> ist "b" | "c"
Extract<U, M>behält Union-Mitglieder, die an M zuweisbar sindExtract<string | number, number> ist number
NonNullable<T>entfernt null und undefinedNonNullable<string | null> ist string

Diese drei arbeiten mit Unions, nicht mit Objekten. Das ist der entscheidende Unterschied zu Pick und Omit, die einen Objekttyp und eine Liste seiner Schlüssel nehmen.

Funktions- und Klassentypen: Parameters, ReturnType und mehr

Utility TypeWas er machtBeispiel
ReturnType<F>der Rückgabetyp eines FunktionstypsReturnType<typeof createStore>
Parameters<F>die Parametertypen als TupelParameters<typeof fetchPage>[0]
ConstructorParameters<C>die Parameter eines Klassenkonstruktors als TupelConstructorParameters<typeof Point>
InstanceType<C>der Instanztyp, den ein Konstruktor erzeugtInstanceType<typeof Point>
ThisParameterType<F>der Typ des this-Parameters einer FunktionThisParameterType<typeof greet>
OmitThisParameter<F>der Funktionstyp ohne seinen this-Parameterder Typ von greet.bind(obj)
ThisType<T>legt den Typ von this in den Methoden eines Objektliterals festmit noImplicitThis in Builder-APIs
NoInfer<T>verhindert, dass ein Typparameter aus dieser Position abgeleitet wirdfallback: NoInfer<C>

typeof createOrder ist nötig, weil diese Utilities einen Typ nehmen und createOrder ein Wert ist. Dasselbe gilt für Klassen: typeof Point ist der Konstruktortyp, während ein einfaches Point als Typ bereits den Instanztyp bedeutet.

NoInfer steuert, woher ein Generic seinen Typ bekommt:

Ohne NoInfer würde TypeScript C aus beiden Argumenten ableiten und auf "red" | "green" | "blue" erweitern, also würde der Tippfehler im Fallback akzeptiert.

String-Typen: Uppercase, Lowercase, Capitalize, Uncapitalize

Utility TypeWas er machtBeispiel
Uppercase<S>schreibt einen String-Literaltyp großUppercase<"get"> ist "GET"
Lowercase<S>schreibt ihn kleinLowercase<"GET"> ist "get"
Capitalize<S>schreibt das erste Zeichen großCapitalize<"name"> ist "Name"
Uncapitalize<S>schreibt das erste Zeichen kleinUncapitalize<"Name"> ist "name"

Diese vier sind im Compiler eingebaut statt in TypeScript geschrieben, und am nützlichsten sind sie in Template Literal Types, etwa `on${Capitalize<E>}` für Namen von Event-Handlern.

Promises: Awaited

Utility TypeWas er machtBeispiel
Awaited<T>der Typ, den du von await bekommst, verschachtelte Promises ausgepacktAwaited<Promise<Promise<number>>> ist number

Awaited<ReturnType<typeof fn>> ist der Standardweg, den Ergebnistyp einer async-Funktion zu benennen, ohne ihn separat zu deklarieren.

Utility Types kombinieren

Utility Types lassen sich verschachteln. Einige Kombinationen kommen oft genug vor, um sie auswendig zu kennen:

Lies einen verschachtelten Utility Type von innen nach außen: Readonly<Pick<Post, "id" | "title">> behält zuerst zwei Eigenschaften und macht sie dann schreibgeschützt. Aus denselben Teilen entsteht ein Helfer PartialBy, der nur einige Schlüssel optional macht; die Partial-Seite schreibt ihn aus.

Utility Types bewirken zur Laufzeit nichts

Jeder Utility Type wird beim Kompilieren entfernt. Ein Wert vom Typ Omit<User, "password"> kann zur Laufzeit trotzdem ein Passwort tragen, wenn das Objekt, aus dem er stammt, eines hatte:

Der Typ schränkt nur ein, was dein Code lesen darf. Um ein Feld aus den Daten zu entfernen, entferne es per Destructuring wie in den letzten Zeilen, und um Änderungen zur Laufzeit zu verhindern, nimm Object.freeze, nicht Readonly. Die eingebauten Typen sind einzeilige Mapped Types und Conditional Types, also kannst du mit denselben Werkzeugen eigene schreiben.

Häufig gestellte Fragen

Was sind Utility Types in TypeScript?

Generische Typen, die mit TypeScript mitkommen und andere Typen umwandeln: Partial<T> macht jede Eigenschaft optional, Pick<T, K> behält einige Eigenschaften, ReturnType<F> liefert den Rückgabetyp einer Funktion und so weiter. Sie sind in der Standardbibliothek deklariert, du nutzt sie also ohne Import.

Muss ich Utility Types importieren?

Nein. Partial, Omit, Record, ReturnType und der Rest sind globale Typen aus den eingebauten Bibliotheksdateien von TypeScript. Schreibe Partial<User> an beliebiger Stelle; weder ein Import noch ein npm-Paket ist nötig.

Welche Utility Types sind in TypeScript eingebaut?

22, alle in lib.es5.d.ts deklariert: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize und Uncapitalize.

Ändern Utility Types Objekte zur Laufzeit?

Nein. Sie beschreiben nur Typen und werden aus der JavaScript-Ausgabe entfernt. Omit<User, "password"> löscht keine Eigenschaft password, und Readonly<T> friert nichts ein. Um das eigentliche Objekt zu ändern, schreibst du den Code: ein Rest-Pattern beim Destructuring, Object.freeze und so weiter.

Kann ich eigene Utility Types schreiben?

Ja. Die eingebauten sind gewöhnliches TypeScript: Die meisten sind einzeilige Mapped Types oder Conditional Types in lib.es5.d.ts. type Nullable<T> = { [K in keyof T]: T[K] | null } ist ein eigener Utility Type, auf dieselbe Weise geschrieben.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S