Pick<T, K> è un utility type integrato che crea un tipo oggetto con le sole proprietà di T nominate in K. Usalo quando una funzione o un componente ha bisogno di pochi campi di un tipo più grande:
renderPreview accetta un User completo e anche un semplice oggetto { id, name }, perché chiede solo ciò che usa. Così è più facile da chiamare e da testare. Pick agisce solo sui tipi: l'oggetto completo ada ha ancora tutte e cinque le proprietà in fase di esecuzione.
Sintassi e controllo delle chiavi
Pick<Type, Keys>
Keys è una singola chiave o un'unione di chiavi, e ognuna deve esistere in Type. La definizione nella libreria standard di TypeScript lo rende un vincolo:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Grazie a K extends keyof T, una chiave scritta male o inesistente è un errore di compilazione, e l'editor può completare automaticamente i nomi delle chiavi:
L'errore è error TS2344: Type '"cost"' does not satisfy the constraint 'keyof Product'. È una differenza rispetto a Omit, le cui chiavi non vengono controllate.
Pick mantiene readonly e opzionale
Pick itera sulle chiavi di T, quindi ogni proprietà selezionata mantiene i suoi modificatori:
L'ultima riga mostra { id: 8 } perché readonly è solo un controllo in fase di compilazione: l'assegnazione è stata segnalata, soppressa con @ts-expect-error, ed è stata comunque eseguita. Per cambiare i modificatori mentre selezioni, avvolgi il risultato: Partial<Pick<Account, "plan">> o Required<Pick<Account, "email">>.
Pick vs Omit
Pick nomina ciò che va tenuto; Omit nomina ciò che va tolto. Oggi entrambi danno lo stesso risultato, ma si comportano in modo diverso quando il tipo di origine cresce:
Pick<T, K> | Omit<T, K> | |
|---|---|---|
| Elenchi | le chiavi da tenere | le chiavi da togliere |
Nuove proprietà su T | non incluse | incluse automaticamente |
Chiave sconosciuta in K | errore di compilazione (TS2344) | accettata in silenzio |
| Adatto a | risposte API, viste pubbliche, props | "tutto tranne il segreto" |
Per i dati che escono dal tuo server, Pick è la scelta predefinita più sicura: nel tipo non compare nulla a meno che qualcuno non l'abbia aggiunto di proposito.
Selezionare da tipi annidati
Pick vede solo le chiavi di primo livello: un percorso con i punti come Pick<Customer, "address.city"> è un errore (TS2344), non una selezione annidata. Usa un indexed access type per raggiungere il tipo annidato, poi seleziona da quello:
Customer["address"] è il tipo della proprietà address. La stessa sintassi raggiunge gli elementi degli array: per una proprietà orders: Order[], Customer["orders"][number] è Order.
Una funzione pick() tipizzata
Pick non fa nulla in fase di esecuzione. Una piccola funzione generica copia le proprietà scelte in un nuovo oggetto e restituisce esattamente Pick<T, K>:
K extends keyof T permette a TypeScript di inferire K dagli argomenti stringa, quindi il tipo di ritorno ha esattamente le chiavi selezionate. L'asserzione {} as Pick<T, K> serve perché un oggetto vuoto non ha ancora quelle proprietà; il ciclo le riempie.
Selezionare proprietà in base al tipo del valore
Pick seleziona per nome della chiave. Per selezionare in base al tipo della proprietà, per esempio "tutti i campi stringa", scrivi un mapped type con un filtro sulle chiavi:
La clausola as mappa ogni chiave su sé stessa quando il suo tipo corrisponde e su never altrimenti, e le chiavi never vengono scartate. Una sottigliezza: il tipo di una proprietà opzionale include undefined, quindi un subtitle?: string opzionale qui non conterebbe come string; confrontalo con string | undefined per includerlo.
Domande frequenti
Cosa fa Pick in TypeScript?
Pick<T, K> costruisce un tipo oggetto che contiene solo le proprietà di T le cui chiavi sono in K. Pick<User, "id" | "name"> è { id: number; name: string } quando User ha quelle due proprietà più altre. Agisce solo sui tipi e non rimuove nulla dagli oggetti in fase di esecuzione.
Che differenza c'è tra Pick e Omit?
Pick elenca le proprietà da tenere, Omit quelle da togliere. Quando il tipo di origine acquista una proprietà, Omit la include automaticamente e Pick no. Inoltre Pick controlla che le sue chiavi esistano nel tipo; Omit accetta qualsiasi chiave.
Come seleziono più proprietà in TypeScript?
Passa un'unione di chiavi: Pick<User, "id" | "name" | "email">. Tutte le chiavi devono esistere in User, altrimenti il compilatore segnala l'errore TS2344.
Come seleziono una proprietà annidata in TypeScript?
Pick seleziona solo proprietà di primo livello. Raggiungi il tipo annidato con un indexed access type e seleziona da lì: Pick<User["address"], "city">. Per mantenere l'annidamento, combinali: Pick<User, "id"> & { address: Pick<User["address"], "city"> }.
Pick mantiene i modificatori readonly e opzionale?
Sì. Pick è un mapped type sulle chiavi di T, quindi una proprietà che è readonly o opzionale in T resta tale nel tipo selezionato.