假设,我们有一个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那样。

10-05 20:44
查看更多