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;
}

Relaterte artikler