Instanceof和type断言

时间:2018-03-15 21:11:09

标签: typescript

在打字稿中,如果我有以下课程:

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)

3 个答案:

答案 0 :(得分:2)

原因是instanceof已被翻译成&#39;到JavaScript。如果你转换代码,你会得到:

&#13;
&#13;
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;
&#13;
&#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"