reactjs - ¿Cómo llamar a un método de clase dinámicamente con una variable evitando el error 7053 de TypeScript?
Este código se ejecuta correctamente, es decir, ejecuta el método llamado import_codeData en la clase DataIimporter llamando dinámicamente a this.import_codeData() basado en el contenido de la variable de cadena task:
Sin embargo, en Visual Studio Code, TypeScript muestra este error:
Obtiene el mismo error si se envía una cadena simple:
Aunque este código funciona bien, ¿cómo puedo hacer que TypeScript no muestre este error en el editor?
APÉNDICE:
Reproduje este error en línea aquí en TypeScript Playground:
class DataImporter {
task: string;
constructor() {
this.task = "import_data001";
}
test() {
this[this.task]();
}
import_data001() {
console.log('importing data001');
}
}
const dataImporter = new DataImporter();
dataImporter.import_data001();
dataImporter.test();
Respuesta #1
Solución en el patio de recreo
El tipo de task necesita ser más específico que solo "string", específicamente keyof DataImporter. Pero cuando haces eso, también puede referirse a claves que nombran no métodos, por lo que necesitarías excluirlos al intentar invocarlos, o como hice yo, comprobar directamente que son funciones.
Tipo de fn:
const fn: "tarea" | "prueba" | "importar_datos001" | (() => void) | (() => void)
Tipo de fn después de considerar solo funciones:
const fn:() => void
class DataImporter {
task: keyof DataImporter;
constructor() {
this.task = "import_data001";
}
test() {
const fn = this[this.task];
if (typeof fn === 'function') { // or !== 'string'
fn();
}
}
import_data001() {
console.log('importing data001');
}
}
const dataImporter = new DataImporter();
dataImporter.import_data001();
dataImporter.test();
Crédito parcial a https://stackoverflow.com/a/56894533/823470 por ayudar con el primer problema. Resolví el segundo simplemente mirando el tipo inferido de fn y viendo que quería considerar solo funciones.
Respuesta #2
Podrías hacer algo como esto (área de juegos):
type GetLength<T extends any[]> = T extends { length: infer L } ? L : never
type ZeroLength<T> = {
[K in keyof T]: T[K] extends () => void ? (GetLength<Parameters<T[K]>> extends 0 ? K : never): never;
}[keyof T]
type Callable = ZeroLength<Foo>
class Foo {
doA() {
}
doB() {
}
doC() {
}
multipleArgs(a: number, b: number) {
return a + b;
}
runSomething(fnName: Callable) {
this[fnName]();
}
}


