Tengo un objeto como este:

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

Me gustaría llamar a estas funciones de esta manera:

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

Desafortunadamente, TypeScript no compila este código.

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

¿Qué debo hacer para habilitar la llamada a la función por el nombre del índice?

#EDIT

Creo este fragmento para mostrar el problema:

Enlace de juegos

1
FabianoLothor 31 jul. 2020 a las 01:28

1 respuesta

La mejor respuesta

El código que proporcionó funciona tal cual, al menos en mecanografiado 3.9.2. Sin embargo, es posible que 1. no funcione de esa manera en una versión anterior de TS, o 2. el código que proporcionó fue simplemente un ejemplo y no es exactamente el código con el que tiene problemas.

En cualquier caso, el error tiene que ver con string y subtipos de string (bar y baz).

El tipo de su objeto Foo se infiere como:

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

En lugar de

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

O en otras palabras, las claves solo pueden ser subtipos específicos de string.

Cuando ejecuta Foo["bar"]();, el último mecanografiado debe interpretar correctamente el índice proporcionado como 'bar', pero es posible que una versión anterior no lo esté haciendo.

Puede evitar esto obligando a TS a interpretarlo como un tipo literal usando un aserción const así:

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

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

Alternativamente, puede proporcionar una anotación de tipo a su objeto Foo con un tipo más amplio así:

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 ago. 2020 a las 16:36