Using TypeScript, I'd like to create a class instances of which have a number of methods, but can be initialized to automatically add several other methods, based off of one of the predefined ones. The base class has a props method, which takes an object, and does stuff with it:
class MyClass {
props(props: Record<string, any>) {
// Do something with passed props
}
}
I want to be able to pass in a list of method names on construction that are then used to dynamically add class instance methods which use this props method to do something. So:
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 });
};
}
});
}
When I try to do so, TS shows an 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)
Is there a way to do this? Saw this semi-related question, but didn't feel applicable. Thanks! New to TS.
EDIT
I tried having the class implement an open interface:
interface CanBeExtended {
[key: string]: any;
}
class MyClass implements CanBeExtended {
// ...
but I think that is making the class itself, but not instances of the class, extensible. At any rate, it is not fixing the issue.
class Child extends Parent(...) {, but it's unsafe anyways because you could accidentally override a built-in or inherited method D:CanBeExtendedextensible, which wprls if you widen aMyClassinstance toCanBeExtended(e.g.,const x: CanBeExtended = new MyClass([])). Animplementsclass is just a check, it doesn't affect the typing. If you wantMyClassinstances to be treated like that you can put an index signature in the class itself, like this. This might be what you want, but this is almost like turning off type safety withinMyClasscompletely. Seems like what you're asking for, though. 🤷♂️