typescript - Hur deklarerar man en valfri generisk typ i ett gränssnitt?
Jag har det här gränssnittet:
export interface AlertInteraction<T> {
id: AlertId;
data: T;
buttonId: AlertButtonId;
}
Men det finns tillfällen då data inte behövs. Jag vet att jag kan deklarera det som data: T men jag skulle vilja veta om jag kunde göra något som detta:
export interface AlertInteraction<T> {
id: AlertId;
data: T;
buttonId: AlertButtonId;
}
export interface AlertInteraction {
id: AlertId;
buttonId: AlertButtonId;
}
Så, om jag anger T antar jag att jag vill få åtkomst till datan, om inte antar jag att den inte finns. Är det möjligt?
Svar #1
För att uppnå det behöver vi använda konditionstyper.
type AlertId = string; // just example type alias
type AlertButtonId = string; // just example type alias
type AlertInteraction<T = undefined> = {
id: AlertId;
buttonId: AlertButtonId;
} & (T extends undefined ? {} : {
data: T;
})
// example usage
// no need for data (T is undefined)
const a: AlertInteraction = {
id: '1',
buttonId: '1'
}
// data prop is required
const b: AlertInteraction<number> = {
id: '1',
data: 1,
buttonId: '1'
}
Det viktigaste är den här delen:
& (T extends undefined ? {} : {
data: T;
})
Vi slår ihop villkorligt eller typ {} om T kan tilldelas undefined, eller vi slår ihop {data: T} för annan typ. I resultat, om vi inte anger generiken, är den som standard undefined och vår typkonstruktor beräknas till:
// For T == undefined
{
id: AlertId;
buttonId: AlertButtonId;
} & {}
// what is equal to just:
{
id: AlertId;
buttonId: AlertButtonId;
}
För ett fall där argumentet (generiskt) ges som något annat än undefined, har den slutliga typen en form:
// For T != undefined
{
id: AlertId;
buttonId: AlertButtonId;
} & { data: T}
// which is equal to
{
id: AlertId;
buttonId: AlertButtonId;
data: T;
}
Där T är typen som ges av argumentet till typkonstruktorn. För att också klargöra informationen - Typkonstruktorn=vilken typdefinition som helst med ett generiskt argument.
