Problem
How can one add type checking to a dynamically created class method?
Example
Given a very simple Property class.
class Property {
value: any;
name: string;
constructor(name: string, value: any) {
this.name = name;
this.value = value
}
}
and an Entity class
class Entity {
name: string;
properties: Property[];
constructor(name: string, properties: Property[]) {
this.name = name;
this.properties = properties;
this.properties.forEach((p: Property, index: number) => {
this[p.name] = (value: string): any => {
if (value) {
this.properties[index].value = value;
}
return this.properties[index].value;
}
}, this);
}
}
Important part: this[p.name] = function ... (we don't know the name of the method at "transpile" time).
We get the following error when transpiling to javascript:
var car = new domain.Entity(
'car',
[
new domain.Property('manufacturer', 'Ford'),
new domain.Property('model', 'Focus')
]
);
car.model() // error TS2339: Property 'model' does not exist on type 'Entity'.
I know that this is a uncommon use of classes as different instances of Entity will have different methods defined. Is there a way to get rid of the error, i.e. typescript is able to identify the proper interface per instance, or at least silent the error?
Notes
This is valid javascript and one could use it in the following manner:
var car = new domain.Entity(
'car',
[
new domain.Property('manufacturer', 'Ford'),
new domain.Property('model', 'Focus')
]
);
car.model() // 'Focus'
car.model('Transit') // 'Transit'
I'm aware that this has been asked on a similar question, but this case is slightly different as the method name is also defined at runtime.