为什么动态对象可以有效地设置为打字稿中的 class
Why is a dynamic object valid to set to a class in typescript
我玩了一点打字稿,发现了这个:
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
所以我的问题是:
为什么在打字稿中将动态对象分配给 class 对象是有效的,而不是真正的 class。好像不是真的class。以后会改善吗?
似乎是黑客攻击。但是这些类型没有干净的 Typescript 函数。这应该更干净,有没有更好的检查功能?
我使用带有严格选项的 Typescript 2.4.2。
因为打字稿只进行编译时检查。
如果您使用下面的 link 并粘贴您的代码并获得 JavaScript
const xxx2: Greeter = { e: 1, p: true };
converts to -->
var xxx2 = { e: 1, p: true };
这只是一个对象,对 class 一无所知 Greeter
Why is it valid in typescript to assign a dynamic object to a class-object, without being the class for real. It seems not to be the real class.
TypeScript 是一种结构语言,而不是名义语言。这意味着检查结构,并且可以使用任何兼容的类型。一旦您开始依赖此语言功能,名义打字就会让您抓狂。
Will this improved in the future?
无法改进!结构类型岩石 :).
但我想正确的答案是 "no - this is by design"。
const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype);
seems to be the hack. But there are no clean Typescript function for the types. This should be cleaner, is there a better checked function?
这个需要一点解构。
第一部分是TypeScript中有一个动态类型:any
。任何具有 any
类型的东西都像变形器。它可以是任意类型。
只要您希望编译器不妨碍并允许您使用动态类型,就可以使用 any
。 (在 "the type can change dynamically" 中是动态的,我注意到您将对象文字描述为 dynamic - 但我在这里谈论的是官方动态类型)。
当您调用 Object.setPrototypeOf(...)
时,它 returns 这些特殊动态类型之一,类型为 any
.
这意味着,当您将它分配给类型为 Greeter
的变量时,这是允许的,因为您有一个 any
类型。
虽然这可能会让您尝试做某事感到沮丧,但我相信您想要实现的目标是可能的 - 所以请随时询问如何实现您需要做的任何事情,我相信我们'我会想办法帮助
从你的 related Github issue 那里得到的。
@Fenton的正确 is laudable evangelism for structural typing as supported in TypeScript. For those occasions where one finds oneself entertaining thoughts of the forbidden fruit of nominal typing,不过,确实有变通办法:
我建议给 Greeter
一个 private member 这样你就不能再给它分配对象字面量了。私有 class 成员似乎是 "standard" 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;
希望对您有所帮助;祝你好运!
我玩了一点打字稿,发现了这个:
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
所以我的问题是:
为什么在打字稿中将动态对象分配给 class 对象是有效的,而不是真正的 class。好像不是真的class。以后会改善吗?
似乎是黑客攻击。但是这些类型没有干净的 Typescript 函数。这应该更干净,有没有更好的检查功能?
我使用带有严格选项的 Typescript 2.4.2。
因为打字稿只进行编译时检查。
如果您使用下面的 link 并粘贴您的代码并获得 JavaScript
const xxx2: Greeter = { e: 1, p: true };
converts to -->
var xxx2 = { e: 1, p: true };
这只是一个对象,对 class 一无所知 Greeter
Why is it valid in typescript to assign a dynamic object to a class-object, without being the class for real. It seems not to be the real class.
TypeScript 是一种结构语言,而不是名义语言。这意味着检查结构,并且可以使用任何兼容的类型。一旦您开始依赖此语言功能,名义打字就会让您抓狂。
Will this improved in the future?
无法改进!结构类型岩石 :).
但我想正确的答案是 "no - this is by design"。
const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype);
seems to be the hack. But there are no clean Typescript function for the types. This should be cleaner, is there a better checked function?
这个需要一点解构。
第一部分是TypeScript中有一个动态类型:any
。任何具有 any
类型的东西都像变形器。它可以是任意类型。
只要您希望编译器不妨碍并允许您使用动态类型,就可以使用 any
。 (在 "the type can change dynamically" 中是动态的,我注意到您将对象文字描述为 dynamic - 但我在这里谈论的是官方动态类型)。
当您调用 Object.setPrototypeOf(...)
时,它 returns 这些特殊动态类型之一,类型为 any
.
这意味着,当您将它分配给类型为 Greeter
的变量时,这是允许的,因为您有一个 any
类型。
虽然这可能会让您尝试做某事感到沮丧,但我相信您想要实现的目标是可能的 - 所以请随时询问如何实现您需要做的任何事情,我相信我们'我会想办法帮助
从你的 related Github issue 那里得到的。
@Fenton的正确
我建议给 Greeter
一个 private member 这样你就不能再给它分配对象字面量了。私有 class 成员似乎是 "standard" 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;
希望对您有所帮助;祝你好运!