typescript - Branded streng som nøkkel for ordbok
På samme måte som spørsmålet TS merkede strenger som nøkkel for objektet, ønsker jeg å bruke merkede strenger som nøkler for min ordbok, men deretter ta det ett skritt videre. I mitt brukstilfelle er den merkede typen av nøkkelen relatert til objektet som er lagret under den nøkkelen.
type HandlerA = { type: "A" };
type HandlerB = { type: "B" };
type HandlerVariant = HandlerA | HandlerB
type Id<T extends HandlerVariant> = string & { __type: T["type"] };
type HandlerDictionary = {
[id: string]: HandlerVariant;
}
Ved å bruke en Map-type kunne jeg håndheve bruken av min merkevarede Id-type for nøkkelen i ordboken som vist nedenfor
type HandlerMap<T extends HandlerVariant> = Map<Id<T>, T>;
Dette betyr dessverre at hele dette kartet måtte være av en av håndterer-typene eller unionen HandlerVariant-typen som har nesten samme effekt som å bare bruke ordboken fra det første eksemplet.
Det jeg gjerne vil kunne gjøre er, avhengig av merket, å utlede riktig type av håndtereren under det på denne måten
const dict = {} as HandlerDictionary;
const key = "" as Id<HandlerA>;
const handler = dict[key];
Siden key er merket med HandlerA-typen, burde det derfor under den nøkkelen være et objekt av typen HandlerA, men typescript utleder dessverre handler til å være av typen HandlerVariant.
Finnes det en måte å skrive denne ordboken på slik at indeks-tilgang er klar over relasjonen mellom nøkkel og verdi? Jeg vet at det finnes måter å gjøre dette på ved å implementere en getter-metode, men i mitt tilfelle ville det bety en betydelig omstrukturering.
// Invalid TS code example of the relationship
type BrandedHandlerDictionary = {
<T extends HandlerVariant>[id: Id<T>]: T;
}