在打字稿中,如果我有以下课程:
class Hello{
public world: string;
}
为什么当我输入assert parsed json为Hello
时,instanceof
返回false?
var json: string = `{"world": "world"}`;
var assertedJson: Hello = JSON.parse(json) as Hello;
var hello: Hello = new Hello();
console.log(assertedJson instanceof Hello); <!-- returns false
console.log(hello instanceof Hello); <!-- returns true (as expected)
答案 0 :(得分:2)
原因是instanceof
已被翻译成&#39;到JavaScript。如果你转换代码,你会得到:
var Hello = /** @class */ (function () {
function Hello() {
}
return Hello;
}());
var json = "{\"world\": \"world\"}";
var assertedJson = JSON.parse(json);
var hello = new Hello();
console.log(assertedJson instanceof Hello);
console.log(hello instanceof Hello);
&#13;
a instanceof b
检查b的原型是否在a的原型链中。您的assertedJson
无法满足此要求。
as
运算符在转换后意味着什么,只是一个注释
答案 1 :(得分:1)
类型断言仅适用于编译时的编译器,它在运行时没有任何影响。开发人员有责任确保编译时类型断言与运行时行为相匹配。
Object
是运行时检查,基本上检查对象是否使用特定的类构造函数创建。它对JSON对象没有多大用处,因为它们是作为内置:
类型的实例创建的。
TypeScript开发人员关于支持与类型系统一致的运行时类型检查的答案是:
https://github.com/Microsoft/TypeScript/issues/2444#issuecomment-85097544
这已被多次提出和讨论过。我们一直在努力 避免将类型系统推入运行时和数量 这种类型实际上适用于(几乎只是类和 原语)不足以证明复杂性与 它启用的用例。
答案 2 :(得分:1)
正如其他人所说,使用as
执行的类型转换对运行时没有影响。但是,作为一种解决方法,您可以手动设置已解析对象的原型,以便它是Hello
的实例,如果您愿意的话:
class Hello {
public world: string;
public sayHello() {
console.log("Hello", this.world);
}
}
var json: string = `{"world": "world"}`;
var assertedJson: Hello = JSON.parse(json) as Hello;
var hello: Hello = new Hello();
console.log(assertedJson instanceof Hello); // <!-- returns false
console.log(hello instanceof Hello); // <!-- returns true (as expected)
// Manual fix:
Object.setPrototypeOf(assertedJson, Hello.prototype);
console.log(assertedJson instanceof Hello); // <!-- returns true
// And doing so will then allow you to access the Hello methods too:
assertedJson.sayHello() // Prints "Hello world"