2
var opts: {n?: number; s?: string;};
opts = {n: 2};     // Ok
opts = {s: 'x'};   // Ok
opts = {};         // Ok
opts = {z: 3};     // Ok, but shouldn't this be an error?

我希望opts对象不接受或接受任何声明的可选属性(但不接受其他属性),但它接受其他未定义的属性,即声明等同于opts: {};,这是一个错误吗?

如果它不是一个错误,你怎么能构造这样的声明?

4

1 回答 1

2

TypeScript 的部分优点在于它非常聪明地决定了一个对象是否可以被强制转换为另一种类型。

您的声明opts实际上没有任何要求,因为这两个属性都是可选的,因此任何任何对象都与此类型兼容。为了兼容,一个对象必须包含所有必需的属性——在这种情况下,没有必需的属性。

如果我们看一个需要属性的调整示例,这会更清楚:

var opts: {a: bool; n?: number; s?: string;};

opts = {a: true, n: 2};     // Ok
opts = {a: true, s: 'x'};   // Ok
opts = {a: true};         // Ok
opts = {a: true,z: 3};     // Ok
opts = {}; // not ok
opts = {z: 3}; // not ok

所以这意味着如果一个对象至少支持所需的属性,它就会被认为是另一个对象的子类型。

这涉及设置对象。现在,如果您考虑使用该对象,您将看到力量所在。因为类型只承诺nsa在我的示例中),所以调用属性的代码n只能请求这些属性。无法访问其他属性:

var opts: {a: bool; n?: number; s?: string;};

opts = {a: true, n: 1, s: 'Hi', z: 3};

var x - opts.z; // not ok

所以我们仍然有类型安全,因为我们只能使用类型声明中的属性——而不是附加属性。

于 2012-11-03T22:35:51.050 回答