Pick<T, K> ist ein eingebauter Utility Type, der einen Objekttyp mit nur den Eigenschaften von T erzeugt, die in K genannt sind. Nutze ihn, wenn eine Funktion oder Komponente ein paar Felder eines größeren Typs braucht:
renderPreview akzeptiert einen vollständigen User und auch ein einfaches Objekt { id, name }, weil es nur das verlangt, was es verwendet. So lässt es sich leichter aufrufen und testen. Pick existiert nur im Typ: Das vollständige Objekt ada hat zur Laufzeit weiterhin alle fünf Eigenschaften.
Syntax und Prüfung der Schlüssel
Pick<Type, Keys>
Keys ist ein einzelner Schlüssel oder eine Union von Schlüsseln, und jeder davon muss in Type existieren. Die Definition in der Standardbibliothek von TypeScript macht das zu einem Constraint:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Wegen K extends keyof T ist ein falsch geschriebener oder fehlender Schlüssel ein Compilerfehler, und dein Editor kann die Schlüsselnamen automatisch vervollständigen:
Der Fehler lautet error TS2344: Type '"cost"' does not satisfy the constraint 'keyof Product'. Das ist ein Unterschied zu Omit, dessen Schlüssel nicht geprüft werden.
Pick behält readonly und optional
Pick iteriert über Schlüssel von T, also behält jede ausgewählte Eigenschaft ihre Modifikatoren:
Die letzte Zeile zeigt { id: 8 }, weil readonly nur beim Kompilieren geprüft wird: Die Zuweisung wurde gemeldet, mit @ts-expect-error unterdrückt und trotzdem ausgeführt. Um die Modifikatoren beim Auswählen zu ändern, umschließe das Ergebnis: Partial<Pick<Account, "plan">> oder Required<Pick<Account, "email">>.
Pick vs Omit
Pick nennt, was bleibt; Omit nennt, was wegfällt. Heute liefern beide dasselbe Ergebnis, aber sie verhalten sich unterschiedlich, wenn der Quelltyp wächst:
Pick<T, K> | Omit<T, K> | |
|---|---|---|
| Du listest auf | die Schlüssel, die bleiben | die Schlüssel, die wegfallen |
Neue Eigenschaften in T | nicht enthalten | automatisch enthalten |
Unbekannter Schlüssel in K | Compilerfehler (TS2344) | stillschweigend akzeptiert |
| Gut für | API-Antworten, öffentliche Ansichten, Props | "alles außer dem Geheimnis" |
Für Daten, die deinen Server verlassen, ist Pick die sicherere Standardwahl: Nichts taucht im Typ auf, außer jemand hat es absichtlich hinzugefügt.
Auswahl aus verschachtelten Typen
Pick sieht nur Schlüssel der obersten Ebene: Ein Pfad mit Punkt wie Pick<Customer, "address.city"> ist ein Fehler (TS2344), keine verschachtelte Auswahl. Nimm einen Indexed Access Type, um den verschachtelten Typ zu erreichen, und wähle dann daraus aus:
Customer["address"] ist der Typ der Eigenschaft address. Mit derselben Syntax erreichst du Array-Elemente: Bei einer Eigenschaft orders: Order[] ist Customer["orders"][number] gleich Order.
Eine typisierte pick()-Funktion
Pick bewirkt zur Laufzeit nichts. Eine kleine generische Funktion kopiert die gewählten Eigenschaften in ein neues Objekt und gibt genau Pick<T, K> zurück:
K extends keyof T lässt TypeScript K aus den String-Argumenten ableiten, also hat der Rückgabetyp genau die ausgewählten Schlüssel. Die Assertion {} as Pick<T, K> ist nötig, weil ein leeres Objekt diese Eigenschaften noch nicht hat; die Schleife füllt sie auf.
Eigenschaften nach ihrem Werttyp auswählen
Pick wählt nach dem Schlüsselnamen aus. Um nach dem Typ der Eigenschaft auszuwählen, zum Beispiel "alle String-Felder", schreibst du einen Mapped Type mit einem Schlüsselfilter:
Die as-Klausel bildet jeden Schlüssel auf sich selbst ab, wenn sein Typ passt, und sonst auf never, und Schlüssel mit never fallen weg. Eine Feinheit: Der Typ einer optionalen Eigenschaft enthält undefined, also würde ein optionales subtitle?: string hier nicht als string zählen; teste gegen string | undefined, um es einzuschließen.
Häufig gestellte Fragen
Was macht Pick in TypeScript?
Pick<T, K> baut einen Objekttyp, der nur die Eigenschaften von T enthält, deren Schlüssel in K stehen. Pick<User, "id" | "name"> ist { id: number; name: string }, wenn User diese beiden Eigenschaften und weitere hat. Es arbeitet nur mit Typen und entfernt zur Laufzeit nichts aus Objekten.
Was ist der Unterschied zwischen Pick und Omit?
Pick listet die Eigenschaften auf, die bleiben, Omit die, die wegfallen. Bekommt der Quelltyp eine neue Eigenschaft, nimmt Omit sie automatisch auf und Pick nicht. Pick prüft außerdem, ob seine Schlüssel im Typ existieren; Omit akzeptiert jeden Schlüssel.
Wie wähle ich in TypeScript mehrere Eigenschaften aus?
Übergib eine Union von Schlüsseln: Pick<User, "id" | "name" | "email">. Die Schlüssel müssen alle in User existieren, sonst meldet der Compiler den Fehler TS2344.
Wie wähle ich in TypeScript eine verschachtelte Eigenschaft aus?
Pick wählt nur Eigenschaften der obersten Ebene aus. Greif mit einem Indexed Access Type auf einen verschachtelten Typ zu und wähle daraus aus: Pick<User["address"], "city">. Um die Verschachtelung zu behalten, kombiniere beides: Pick<User, "id"> & { address: Pick<User["address"], "city"> }.
Behält Pick die Modifikatoren readonly und optional?
Ja. Pick ist ein Mapped Type über Schlüssel von T, also bleibt eine Eigenschaft, die in T readonly oder optional ist, im ausgewählten Typ genauso.