比方说,我们在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服务接收到的。)
答案 0 :(得分:3)
即使我强制转换对象,错误也不会消失。
Type assertions(它们不是强制转换)对对象没有任何影响。在那里添加类型断言的所有事情都是使TypeScript认为对象不是Greeter
。
- 这是一个错误吗?
不是在TypeScript或JavaScript中,
- 有没有更好的方法来解决这个问题?
如果您有一个非fromGreeter
对象,并且您的object
对象是一个合理的方法(尽管类型注释应为Greeter
,而不是Greeter
),您要用来创建greeting
的{{1}}属性(以及其他属性)。或者,您可能会重载构造函数,使其接受纯对象并复制属性。
如果您希望普通对象仅具有应在问候者上显示的有效属性,则可以使用Greeter
将其复制到新实例:
Object.assign
如果我不说更改对象原型是可能(从ES2015起)的话,我会很失落,但是不建议这样做,它会影响性能。因此,可能会使用public static fromObject(greeter: object): Greeter {
return Object.assign(new Greeter(), greeter);
}
将现有的普通对象实际转换为某种东西,这是可能的:
Greeter.prototype
就像您的// Not recommended, but possible
Object.setPrototypeOf(plainObject, Greeter.prototype);
一样,创建新实例并将属性复制到它几乎总是更好。