Fortgeschritten
TypeScript Utility Types: Partial, Pick, Omit und mehr
Die wichtigsten eingebauten Utility Types in TypeScript erklärt: Partial, Pick, Omit, Required, Readonly und ihre praktischen Anwendungsfälle.
Inhalt
TypeScript Utility Types: Partial, Pick, Omit und mehr
TypeScript kommt mit einer Reihe eingebauter Hilfswerkzeuge, die sogenannten Utility Types. Sie erlauben es, bestehende Typen umzuformen, einzuschränken oder zu erweitern, ohne dabei Code zu duplizieren. Wer sie kennt, schreibt sauberere und wartbarere Typdefinitionen.
Warum Utility Types?
In der Praxis willst du oft nicht immer denselben Typ verwenden. Für ein Formular brauchst du vielleicht alle Felder als optional. Für eine API-Antwort willst du nur eine Teilmenge. Für schreibgeschützte Konfigurationen sollen Felder unveränderbar sein.
Ohne Utility Types müsstest du jedes Mal einen neuen Typen von Hand schreiben. Mit ihnen leitest du neue Typen systematisch aus bestehenden ab.
Partial
Partial macht alle Felder eines Typs optional. Das ist nützlich bei Update-Operationen, bei denen der Aufrufer nur die zu ändernden Felder angeben soll.
interface Nutzer {
id: number;
name: string;
email: string;
aktiv: boolean;
}
// Alle Felder optional
type NutzerUpdate = Partial<Nutzer>;
function aktualisiereNutzer(id: number, aenderungen: NutzerUpdate) {
// Nur die übergebenen Felder werden verarbeitet
console.log(id, aenderungen);
}
aktualisiereNutzer(1, { name: "Max" });
aktualisiereNutzer(2, { email: "max@beispiel.de", aktiv: false });
Required
Required ist das Gegenteil von Partial. Es macht alle optionalen Felder eines Typs zu Pflichtfeldern.
interface Einstellungen {
sprache?: string;
zeitzone?: string;
darkMode?: boolean;
}
// Alle Felder jetzt Pflicht
type VollstaendigeEinstellungen = Required<Einstellungen>;
const standard: VollstaendigeEinstellungen = {
sprache: "de",
zeitzone: "Europe/Berlin",
darkMode: false,
};
Readonly
Readonly verhindert, dass Felder nach der Initialisierung verändert werden. Das ist besonders für Konfigurationsobjekte und Zustandsobjekte in Redux-ähnlichen Architekturen nützlich.
interface Konfiguration {
apiUrl: string;
timeout: number;
}
const config: Readonly<Konfiguration> = {
apiUrl: "https://api.beispiel.de",
timeout: 5000,
};
// Fehler: Cannot assign to 'apiUrl' because it is a read-only property.
config.apiUrl = "https://anderes-api.de";
Pick
Pick erstellt einen neuen Typen, der nur die angegebenen Felder des ursprünglichen Typs enthält.
interface Artikel {
id: number;
titel: string;
inhalt: string;
autor: string;
veroeffentlichtAm: Date;
tags: string[];
}
// Nur die Felder für eine Artikel-Vorschau
type ArtikelVorschau = Pick<Artikel, "id" | "titel" | "autor" | "veroeffentlichtAm">;
function zeigeVorschau(artikel: ArtikelVorschau) {
console.log(`${artikel.titel} von ${artikel.autor}`);
}
Im Playground siehst du sofort, welche Felder ArtikelVorschau enthält, wenn du mit der Maus über den Typen fährst.
Omit
Omit ist das Gegenstück zu Pick. Es erstellt einen neuen Typen, der alle Felder des ursprünglichen Typs enthält, außer den angegebenen.
interface Produkt {
id: number;
name: string;
preis: number;
internerCode: string;
einkaufspreis: number;
}
// Interne Felder weglassen, bevor Produkt an den Client geschickt wird
type OeffentlichesProdukt = Omit<Produkt, "internerCode" | "einkaufspreis">;
function sendeanClient(produkt: OeffentlichesProdukt) {
// internerCode und einkaufspreis fehlen jetzt im Typen
console.log(produkt);
}
Record
Record erstellt ein Objekt mit einem fixen Set an Schlüsseln und einem bestimmten Werttypen.
type Sprache = "de" | "en" | "pl";
type Uebersetzungen = Record<Sprache, string>;
const begruessung: Uebersetzungen = {
de: "Hallo",
en: "Hello",
pl: "Cześć",
};
Record ist besonders nützlich, wenn die erlaubten Schlüssel durch ein Union-Type definiert sind.
Extract und Exclude
Diese beiden Utility Types arbeiten auf Union Types statt auf Objekt-Interfaces.
type Zahlentypen = "integer" | "float" | "string" | "boolean";
// Nur die Zahlen-bezogenen Typen
type NurZahlen = Extract<Zahlentypen, "integer" | "float">;
// Ergebnis: "integer" | "float"
// Alles außer string
type OhneString = Exclude<Zahlentypen, "string">;
// Ergebnis: "integer" | "float" | "boolean"
Utility Types kombinieren
Der wahre Nutzen kommt zum Vorschein, wenn du Utility Types kombinierst:
interface Formularfeld {
name: string;
wert: string;
fehler: string;
beruehrt: boolean;
}
// Nur name und wert, und beide optional
type TeilFormular = Partial<Pick<Formularfeld, "name" | "wert">>;
// Alle Felder außer fehler, und alle readonly
type AusgabeFeld = Readonly<Omit<Formularfeld, "fehler">>;
Fazit
Utility Types sind eine der produktivsten Funktionen in TypeScript. Statt Typen immer wieder von Hand zu definieren, leitest du sie systematisch aus einem einzigen Basis-Interface ab. Ändert sich das Basis-Interface, passen sich alle abgeleiteten Typen automatisch an.
Häufige Fragen
Was ist der Unterschied zwischen Pick und Omit?
Pick wählt gezielt die Felder aus, die im neuen Typen enthalten sein sollen. Omit schließt gezielt Felder aus und behält alle anderen. Pick ist besser, wenn du nur wenige Felder brauchst. Omit ist besser, wenn du fast alle Felder behalten und nur einzelne entfernen willst.
Kann ich Utility Types kombinieren?
Ja, Utility Types lassen sich beliebig verschachteln. Zum Beispiel kannst du 'Partial' und 'Pick' kombinieren: Partial<Pick<Nutzer, 'name' | 'email'>> ergibt einen Typen mit optionalen name- und email-Feldern.
Quellen
- TypeScript Handbook: Utility Types (typescriptlang.org)
Über die Autorenschaft
Jan-Tristan Rudat
Redakteur typescript-playground.de
Themengebiet: Generationen, Kulturgeschichte, Sternzeichen, Pop-Phänomene rund ums Alter
Mehr über Jan-Tristan Rudat →Verwandte Artikel
Grundlagen
Was ist TypeScript? Eine Einführung in die typisierte JavaScript-Erweiterung
TypeScript erweitert JavaScript um statische Typen und macht große Codebases wartbarer. Lerne die Grundlagen, die Geschichte und die wichtigsten Vorteile von TypeScript.
Lesezeit 7 Min.
Grundlagen
TypeScript vs. JavaScript: Die wichtigsten Unterschiede im Überblick
TypeScript und JavaScript unterscheiden sich grundlegend in der Typprüfung, Werkzeugunterstützung und Wartbarkeit. Dieser Ratgeber erklärt die Unterschiede und hilft bei der Wahl der richtigen Sprache.
Lesezeit 8 Min.
Typen
TypeScript Typen Grundlagen: string, number, boolean und mehr
Die primitiven Typen string, number und boolean sind das Fundament von TypeScript. Dieser Ratgeber erklärt alle grundlegenden Typen mit praktischen Beispielen.
Lesezeit 9 Min.