javascript - Hvordan kan jeg kjøre en funksjon i et objekt ved hjelp av nøkkelnavnet ditt i TypeScript?


Jeg har et objekt som dette:

const Foo = {
    bar: (): void => { console.log('foo.bar') },
    baz: (): void => { console.log('foo.baz') },
};

Jeg vil gjerne kalle disse funksjonene på denne måten:

Foo["bar"]();
Foo["baz"]();

Dessverre kompilerer ikke TypeScript denne koden.

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type {MY_OBJECT}

Hva må jeg gjøre for å aktivere funksjonskallet etter indeksnavnet?

#REDIGER

Jeg lager dette utdraget for å vise problemet:

Lekeromlenke

Svar #1

Koden du ga fungerer som den er, i det minste i TypeScript 3.9.2. Det er imidlertid mulig at enten 1. det ikke fungerer på den måten i en tidligere versjon av TS, eller 2. koden du ga bare var et eksempel og ikke nøyaktig den koden du har problemer med.

I begge tilfeller har feilen å gjøre med string og underkategorier av string (bar og baz).

Objektet ditt Foo sin type blir antatt å være:

{ [key in 'bar' | 'baz']: () => void }

i motsetning til

{ [key in string]: () => void }

eller med andre ord, nøklene kan bare være spesifikke under-typer av string.

Når du kjører Foo["bar"]();, bør den nyeste versjonen av TypeScript korrekt tolke indeksen som 'bar', men en tidligere versjon kan muligens ikke gjøre det.

Du kan komme rundt dette ved å tvinge TS til å tolke dette som en bokstavelig type ved å bruke en const-erklæring slik:

const key1 = 'bar' as const
Foo[key1]() // should not error

const key2 = 'baz' as const
Foo[key2]() // should not error

Alternativt kan du gi en typeannotasjon til ditt Foo-objekt med en bredere type på følgende måte:

const Foo: {[key in string]: () => void} = {
    bar: (): void => { console.log('foo.bar') },
    baz: (): void => { console.log('foo.baz') },
};

Foo['bar']() // should not error
Foo['baz']() // should not error

Relaterte artikler