假设,我们有一个typescript类:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
如果你这样做了:
let greeter = new Greeter('World');
greeter.greet();
一切正常。
但是,如果您这样做:
let greeter = {greeting: 'World'};
greeter.greet();
它抛出一个错误:
ERROR TypeError: greet is not a function
现在,我知道是什么导致了这个错误。它是一个普通的对象,被分配给类对象,不知道greet()是什么。
即使我输入了对象,错误也不会消失。
let greeter = {greeting: 'World'} as Greeter;
我通过在类中放置一个静态函数来解决这个问题,比如:
public static fromObject(greeter: Greeter) {
return new Greeter(greeter.greeting);
}
所以,我有两个问题:
这是虫子吗?
有没有更好的方法来解决这个问题?
(我有一个简单对象的原因是我从web服务接收它。)
最佳答案
即使我输入了对象,错误也不会消失。
Type assertions(他们没有施法)对物体没有任何影响。添加类型断言所做的一切只是让typescript认为对象是Greeter
而不是。
这是虫子吗?
不在typescript或javascript中,不。
有没有更好的方法来解决这个问题?
如果您有一个具有要从中创建fromGreeter
属性(可能还有其他属性)的非object
对象,则Greeter
是接近它的合理方法(尽管类型注释应该是Greeter
,而不是greeting
)。或者您可以重载构造函数,使其接受一个普通对象并复制属性。
如果您希望信任普通对象将只具有应位于迎接器上的有效属性,则可以使用Greeter
将它们复制到新实例:
public static fromObject(greeter: object): Greeter {
return Object.assign(new Greeter(), greeter);
}
如果我不说有可能(从ES2015年起)改变一个对象的原型,那我就失职了,但不建议这样做,而且会影响性能。因此,可以使用
Object.assign
将现有的纯对象实际转换为某些对象:// Not recommended, but possible
Object.setPrototypeOf(plainObject, Greeter.prototype);
几乎总是最好创建一个新实例并将属性复制到它,就像
Greeter.prototype
那样。