为什么动态对象在typescript中设置为类是有效的

时间:2017-11-30 17:21:01

标签: javascript typescript instanceof

我玩过一些打字稿,发现了这个:

class Greeter {
  e: number;

  p: boolean = true;
}

const xxx = new Greeter(); // true
console.log(xxx instanceof Greeter);
const xxx2: Greeter = { e: 1, p: true }; // <--- 1. why is this valid?
console.log(xxx2 instanceof Greeter); // false

const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype); // <-- 2. no warning?
console.log(xxx2 instanceof Greeter); // true

所以我的问题是:

  1. 为什么在typescript中将动态对象分配给类对象是有效的,而不是真正的类。它似乎不是真正的阶级。这会在未来有所改善吗?

  2. 似乎是黑客攻击。但是类型没有干净的Typescript函数。这应该更干净,有更好的检查功能吗?

  3. 我使用Typescript 2.4.2和严格的选项。

3 个答案:

答案 0 :(得分:2)

  

为什么在typescript中将动态对象分配给类对象是有效的,而不是真正的类。它似乎不是真正的阶级。

TypeScript是一种结构语言,而不是名义语言。这意味着检查结构,并且可以使用任何兼容类型。一旦你开始依赖这种语言功能,名义上的打字就会让你疯狂。

  

将来会有所改善吗?

无法改进!结构类型摇滚:)。

但我认为正确答案是“不 - 这是设计”。

  

const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype);似乎是黑客攻击。但是类型没有干净的Typescript函数。这应该更干净,有更好的检查功能吗?

这个需要一点点解构。

第一部分是TypeScript中有一个动态类型:any。任何类型为any的东西都像变形者。它实际上可以是任何类型。

只要您希望编译器不受影响并允许您使用动态类型,就可以使用any。 (动态,如“类型可以动态更改”,我注意到您将对象文字描述为动态 - 但我在这里谈论的是官方动态类型。)

当您致电Object.setPrototypeOf(...)时,它会返回其中一种特殊动态类型,其类型为any

这意味着,当您将其分配给类型为Greeter的变量时,它是允许的,因为您有any类型。

虽然这可能令你感到沮丧,但我确信你想要达到的目标是可能的 - 所以请随时询问如何实现你需要做的事情,我相信我们会来一种帮助的方式

答案 1 :(得分:0)

由于打字稿只进行编译时检查。

如果您使用以下链接并粘贴代码并获取JavaScript

const xxx2: Greeter = { e: 1, p: true }; 

converts to -->

var xxx2 = { e: 1, p: true }; 

这只是一个对象,对类Greeter

一无所知

https://www.typescriptlang.org/play/index.html

答案 2 :(得分:0)

来自related Github issue

@ Fenton的正确answer对于TypeScript支持的结构打字是值得称赞的传福音。然而,对于那些发现自己对nominal typing的禁果有趣的想法的场合,确实存在变通方法:

我建议您Greeter private member,以便您不再为其分配对象字面值。私有类成员似乎是名义键入的“标准”TypeScript解决方法。

示例:

class Greeter {
  private _nominal = true; // add something like this
  e: number;
  p: boolean = true;
}

const xxx = new Greeter();
const xxx2: Greeter = { e: 1, p: true }; // error, missing _nominal
const xxx3: Greeter = { e: 1, p: true, _nominal: true }; // error, _nominal is private

这对你有用吗?这至少会让自己陷入困境更加困难,尽管如果你真的尝试,你会成功:

// don't do this
const xxx4: Greeter = function() { return "ha ha fooled you";} as any as Greeter; 

希望有所帮助;祝你好运!