typescript - 为类对象赋值后出现“TypeError:XXXX 不是函数”
问题描述
假设我们在 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 服务接收它。)
解决方案
即使我对对象进行类型转换,错误也不会消失。
类型断言(它们没有强制转换)对对象没有任何影响。在那里添加类型断言所做的只是让 TypeScript 认为对象是 aGreeter
而不是。
- 这是一个错误吗?
不在 TypeScript 或 JavaScript 中,不。
- 有没有更好的方法来解决这个问题?
如果您有一个具有要从中创建的属性(可能还有其他属性)的非对象,那么您fromGreeter
是一种合理的方法来处理它(尽管类型注释应该是object
,而不是) 。或者您可能会重载构造函数,以便它接受一个普通对象并复制属性。Greeter
Greeter
greeting
Greeter
如果您想相信普通对象只会具有应在欢迎程序上的有效属性,您可以使用Object.assign
将它们复制到新实例:
public static fromObject(greeter: object): Greeter {
return Object.assign(new Greeter(), greeter);
}
如果我没有说可以(从 ES2015 开始)更改对象的原型,那我就是失职了,但不建议这样做并且会影响性能。因此,可以使用以下方法将现有的普通对象实际转换为某种东西Greeter.prototype
:
// Not recommended, but possible
Object.setPrototypeOf(plainObject, Greeter.prototype);
就像您一样,创建一个新实例并将属性复制到它几乎总是更好fromObject
。
推荐阅读
- java - 单击按钮时未加载新的 FXML 场景
- wpf - 如何签署窗体应用程序,因为它不是我的选择
- c++ - 获取结构成员的指针后无法正确访问
- javascript - 如何从 fetch REACT.js 中显示地图功能
- android - 如何使用 QT 在 Android 设备上显示图像?
- prolog - 最新的 Prolog 实现基准?
- kubernetes - Vault 代理注入器坏证书
- python - 查找大小小于 x 的某些颜色的色块。(x =像素数)
- android-studio - 找不到扩展实现类 org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
- vue.js - 将 Granim 导入 Vue