TypeScript: proprietà selezionate facoltative con Parziale & Ometti
Quando si utilizza l’utilità Partial
su un tipo, tutte le proprietà del tipo saranno facoltative. Vediamo come possiamo comporre questa utility con un’altra, Omit
, per rendere opzionali solo alcune proprietà di questo tipo. Creeremo infine un tipo di utilità utilizzando i generici TypeScript per applicarlo a qualsiasi tipo desideriamo.
Rendi facoltative tutte le proprietà di un tipo
Le utilità Partial
e Omit
sono ben note nel regno di TypeScript perché sono molto utili per applicarle rapidamente a un tipo e ottenere quello che è fondamentalmente un nuovo tipo. Partial<T>
convertirà tutte le chiavi di un tipo in facoltative. Se ad esempio hai questo tipo:
interface Band {
lead: string
guitar: string
bass: string
drums: string
keyboard: string
}
tutte le proprietà sono richieste quando qualcosa ha questo tipo. Se vuoi assegnare un oggetto come questo:
const FooFighters: Band = {
lead: 'Dave Grohl',
guitar: 'Pat Smears',
bass: 'Nate Mendel',
drums: 'Taylor Williams',
}
fallirà perché manca la keyboard
proprietà. Ora, potremmo contrassegnare questa proprietà come opzionale e TypeScript ce lo consente facilmente. Il modo più semplice per farlo è aggiungere un punto interrogativo al suo nome. In questo caso, se è possibile modificare il tipo originale, puoi accedervi e modificarlo in questo modo:
interface Band {
lead: string
guitar: string
bass: string
drums: string
keyboard?: string
}
Grande. Ora l’assegnazione precedente andrà a buon fine perché keyboard
non è più richiesta. Ma cosa succede se non è possibile cambiare il tipo originale per qualsiasi motivo? Quello che puoi fare rapidamente in questi casi è applicare Partial
a questo tipo:
type NotAllTheBand = Partial
const FooFighters: NotAllTheBand = {
lead: 'Dave Grohl',
guitar: 'Pat Smears',
bass: 'Nate Mendel',
drums: 'Taylor Williams',
}
Ciò interrompe l’applicazione di tutte le proprietà, rendendole tutte facoltative. Forse a volte lo vogliamo, ma cosa succede se vogliamo solo rendere opzionale una sola proprietà ed evitare di modificare il tipo originale?
Rimozione di proprietà da un tipo
Prima di passare ad esso e vedere come funziona, vediamo un’altra utility che ci aiuterà in questo: Omit
. Questo tipo di utilità rimuove le proprietà dal tipo a cui è applicato. Sebbene Partial
non accetti altri argomenti oltre al tipo, Omit
prende il tipo più le proprietà che desideri rimuovere: Omit<T, K>
.
Non è Partial
che li renda opzionali: Omit
li cancellerà completamente dal tipo. Quando lo usi Partial<Band>
è come se avessi fatto questo:
interface Band {
lead?: string
guitar?: string
bass?: string
drums?: string
keyboard?: string
}
Tuttavia, quando usi Omit<Band, 'keyboard'>
, è come se avessi fatto questo:
interface Band {
lead: string
guitar: string
bass: string
drums: string
}
Questo ora sta iniziando ad avere senso, giusto? Riesci a immaginare cosa potremmo fare in TypeScript se avessimo un tipo che ha tutte le proprietà dell’originale impostate su opzionali e un altro tipo che ha solo le proprietà che vogliamo richiedere? Se solo ci fosse un modo per… intersecare questi tipi, giusto?
Tipi intersecanti
Sì, c’è un modo in TypeScript usando la e commerciale &
, l’operatore di intersezione del tipo. Questo operatore, dati due tipi, ne costruisce uno nuovo con le proprietà che appartengono a entrambi i tipi:
interface SomeType {
propA: string
propB: number
}
interface AnotherType {
propC: boolean
propD: Array
}
type IntersectedType = SomeType & AnotherType
A questo punto probabilmente l’hai capito: incroceremo un tipo parzializzato e un tipo in cui abbiamo rimosso alcune delle sue proprietà.
Rendi facoltative le proprietà selezionate di un tipo
Proviamo a dargli un senso. È importante quando si impara TypeScript per razionalizzare ciò che sta accadendo con i nostri tipi.
Prenderemo un tipo che ha tutte le sue proprietà impostate su facoltative grazie Partial
all’applicazione su di esso. Successivamente, lo intersecheremo con un tipo che ha selezionato le proprietà rimosse da Omit
. Vediamo un esempio:
interface SomeType {
propA: string
propB: number
}
type OptionalPropB = Partial & Omit
Ora abbiamo un nuovo tipo, senza modificare il tipo originale, che assomiglia al seguente:
type OptionalPropB = {
propA: string
propB?: string
}
Ciò accade perché estraiamo proprietà propA?
e propB?
dal tipo prodotto da Partial
e le intersechiamo con propA
il tipo prodotto da Omit
.
Utilità generiche TypeScript
Ok, ora il nostro nuovo tipo funziona e possiamo avere solo le proprietà selezionate contrassegnate come opzionali senza modificare il tipo originale. Tuttavia, questa linea
type OptionalPropB = Partial & Omit
È troppo prolisso, piuttosto brutto e noioso da scrivere ogni volta. Ancora più importante, non funzionerà con un tipo diverso, dovremo scriverlo di nuovo ogni volta. Possiamo renderlo più corto e più carino e farlo funzionare per qualsiasi tipo? Sì, TypeScript ci consente di utilizzare qui i generici e creare il nostro tipo di utilità:
type Optional = Partial & Omit
E ora abbiamo il nostro tipo di utilità TypeScript implementato con generici che possiamo utilizzare per rendere le proprietà del tipo selezionato opzionali in qualsiasi tipo. Possiamo usarlo in questo modo:
type TypeWithOptionalProp = Optional
Noterai che la firma è simile a Omit: questa utility prende il tipo su cui operare e le proprietà che saranno rese opzionali. Se ne hai di più, puoi utilizzare l’operatore union:
type TypeWithOptionalProps = Optional
Parole di chiusura
Ora puoi salvare questo tipo di utilità generico in un file ed esportarlo per usarlo nell’intera app. Ecco un collegamento a un playground TypeScript in cui ho aggiunto il codice di questo articolo e l’ho commentato in modo che tu possa vedere cosa sta succedendo, guardando Partial
, Omit
e il nostro tipo di utilità generico.
Il mondo dei generici e dei programmi di utilità è fantastico in TypeScript. Entra e inizia a sperimentare!