Mam taki obiekt:

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

Chciałbym zadzwonić do tych funkcji w ten sposób:

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

Niestety, maszynopis nie kompila się tego kodu.

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

Co muszę zrobić, aby włączyć wywołanie funkcji przez nazwę indeksu?

#edit

Tworzę ten fragment, aby pokazać problem:

Link do placu zabaw

1
FabianoLothor 31 lipiec 2020, 01:28

1 odpowiedź

Najlepsza odpowiedź

Kod, który dostarczyłeś, co oznacza, co najmniej w maszynach 3.9.2. Możliwe jest jednak, że albo 1. nie działa w ten sposób w wcześniejszej wersji TS lub 2. Podany kod był po prostu przykładem i nie jest dokładnie kodem, z którym masz problemy z.

W obu przypadkach błąd ma związek z string i podtypami string (bar i baz).

Twój obiekt Foo typ jest wywnioskowany jako:

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

W przeciwieństwie do

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

Lub innymi słowy, klucze mogą być specyficznymi podrobniami string.

Po uruchomieniu Foo["bar"]();, najnowszy typ typów należy poprawnie zinterpretować indeks dostarczony jako 'bar', ale wcześniejsza wersja może tego nie robić.

Można go obejść, wymuszając TS do interpretacji tego jako dosłownego typu za pomocą Const Asertion jak:

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

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

Alternatywnie możesz dostarczyć adnotacji typu do obiektu Foo z szerszym typem, jak:

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
1
g2jose 3 sierpień 2020, 16:36