如何将类型检查添加到动态创建的类方法中?
给出一个非常简单的Property
类。
class Property {
value: any;
name: string;
constructor(name: string, value: any) {
this.name = name;
this.value = value
}
}
和Entity
类
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);
}
}
重要部分:this[p.name] = function ...
(我们不知道"方法的名称和#34;时间)。
转换为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'.
我知道这是一种不常见的类使用,因为Entity
的不同实例将定义不同的方法。有没有办法摆脱错误,即打字稿能够识别每个实例的正确接口,或者至少沉默错误?
这是有效的javascript,可以通过以下方式使用它:
var car = new domain.Entity(
'car',
[
new domain.Property('manufacturer', 'Ford'),
new domain.Property('model', 'Focus')
]
);
car.model() // 'Focus'
car.model('Transit') // 'Transit'
我知道这已在similar question上被询问,但这种情况略有不同,因为方法名称也是在运行时定义的。
答案 0 :(得分:0)
添加此类型(只需一次):
interface Prop<T> {
(): T;
(value: T): T;
}
然后你可以为你创建的每个形状写这个:
interface Car extends Entity {
model: Prop<string>;
manufacturer: Prop<string>;
}
let car = <Car>new Entity('car', [/*...*/]);
car.model(32); // Error
let x = car.model(); // x: string
答案 1 :(得分:0)
如果您要访问动态属性,请使用任意类型来绕过变量的类型检查。您可以使用get go中的 any 类型声明变量,或者稍后使用类型断言运算符( as )。所以这里有一些可能的变种:
var car: any = new domain.Entity(...);
car.model();
var car = new domain.Entity(...) as any;
car.model();
var car = new domain.Entity(...);
(car as any).model();