Usando TypeScript, me gustaría crear instancias de clase que tengan varios métodos, pero que se puedan inicializar para agregar automáticamente varios otros métodos, basados en uno de los predefinidos. La clase base tiene un método props , que toma un objeto y hace cosas con él:
class MyClass { props(props: Record<string, any>) { // Do something with passed props } } Quiero poder pasar una lista de nombres de métodos en construcción que luego se usan para agregar dinámicamente métodos de instancia de clase que usan este método de props para hacer algo. Asi que:
constructor(propList: Array<string> = []) { propList.forEach(propName => { // Don't allow overwriting of existing methods if (this[propName]) { throw new Error( `Cannot create prop setter for '${propName}'. Method with that name already exists!` ); } else { this[propName] = (value: any) => { this.props({ [propName]: value }); }; } }); }Cuando intento hacerlo, TS muestra un error:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'MyClass'. No index signature with a parameter of type 'string' was found on type 'MyClass'.ts(7053)
¿Hay alguna forma de hacer esto? Vi esta pregunta semirelacionada , pero no me pareció aplicable. ¡Gracias! Nuevo en TS.
EDITAR
Intenté que la clase implementara una interfaz abierta:
interface CanBeExtended { [key: string]: any; } class MyClass implements CanBeExtended { // ...pero creo que eso es hacer que la clase en sí, pero no las instancias de la clase, sea extensible. En cualquier caso, no está solucionando el problema.
Puede declarar una firma de índice en una class , siempre que no entre en conflicto con los tipos de otros miembros (por lo que si tiene un método props() , no puede hacer que la firma de índice [k: string]: number , por ejemplo, ya que props es un método y no un number ). En su caso, desea usar any type , que definitivamente no entrará en conflicto (aunque tampoco es muy seguro). Entonces se ve así:
class MyClass { [k: string]: any; // index signature constructor(propList: Array<string> = []) { propList.forEach(propName => { // Don't allow overwriting of existing methods if (this[propName]) { // no error here anymore throw new Error( `Cannot create prop setter for '${propName}'. Method with that name already exists!` ); } else { this[propName] = (value: any) => { // no error here anymore this.props({ [propName]: value }); }; } }); } props(props: Record<string, any>) { // Do something with passed props } }Y tus errores desaparecen.