为什么仅通过将对对象的引用传递给函数而不是将对象传递为原义形式,就可以避免打字稿中过多的属性检查?

时间:2018-10-17 10:06:50

标签: typescript

看看这个示例打字稿代码

function printLabel(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

printLabel({ size: 10, label: 'hello' });

上面的代码无法编译,并出现以下错误:

  

1.ts:6:14-错误TS2345:类型为'{size:number;标签:字符串; }'不可分配给类型'{label:string; }'。     对象文字只能指定已知的属性,并且'size'在类型'{label:string; }'。

简而言之,size是一个多余的属性,不符合类型{ label: string },导致编译器大喊大叫。让我们稍微修改一下上面的代码片段:

function printLabel(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}
const obj = { size: 10, label: 'hello' }
printLabel(obj);

现在,我们将在先前示例中传递给printLabel的对象文字提取到名为obj的中间引用中,奇怪的是,现在它不会抱怨并且可以正常工作。为什么打字稿会这样?

2 个答案:

答案 0 :(得分:3)

这是设计使然。简而言之,Typescript的创建者采用这种方式是因为他们知道Javascript是一种非常动态的语言,具有许多这样的用例。

您应该仔细阅读以下内容:https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks (不过我敢打赌,问题是阅读该问题而产生的。)

  

对象文字得到特殊处理

他们的逻辑可能是这样的:如果您有一个变量,那么它可能来自某个第三方,那么您将无能为力。另一方面,如果传递对象文字,则负责其正确的类型。

答案 1 :(得分:0)

如果你为对象字面量被分配的类型编写了一个具有多余属性的对象字面量,那么多余的属性就不可能以类型安全的方式访问——只有一个对该对象的引用(传递到使用对象字面量),并且该引用具有不太具体的类型,它不知道多余的属性。所以这些额外的属性是无法通过合理编写的代码访问的,这意味着您可能犯了一个错误。

当对象第一次被变量引用时,变量的类型是从对象推断出来的,变量的类型是特定的,所以这些额外的属性仍然可以通过该变量以类型安全的方式访问。所以额外的属性不是不可访问的,也没有证据表明你犯了错误。