在类型检查中传递命名对象和匿名对象之间的差异

时间:2017-11-28 19:54:10

标签: typescript

考虑以下代码

interface Config {
    label?: string;
    width?: number;
}

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

let myObj = {not_in_interface: 10, label: "Size 10 Object"};

// No error
printLabel(myObj);

// Will run into error  Argument of type '{ not_in_interface: number; label: string; }' is not assignable to parameter of type 'Config'
printLabel({not_in_interface: 10, label: "Size 10 Object"});

出现差异的原因是什么?

似乎匿名对象触发excess property checking而命名对象则不会。

1 个答案:

答案 0 :(得分:3)

TypeScript仅检查声明对象文字的位置的多余属性(如您在问题中所述)。 The TypeScript docs describe this check :(也可以随时查看full spec here。)

  

TypeScript 1.6强制执行更严格的对象文字赋值检查,以捕获多余或拼写错误的属性。具体来说,当一个新对象文字被分配给一个变量或作为一个非空目标类型的参数传递时,对象文字指定一个目标类型中不存在的属性是错误的。

那为什么会这样呢?简而言之,在某些用例中,您希望在传递对象时允许额外的属性,而在其他用例中则不需要。例如,如果下面的printWeightInPounds函数不接受我们的Dog对象,那就太遗憾了:

interface Animal { weight: number; }
interface Dog extends Animal { breed: string; }

const myDog: Dog = { weight: 100, breed: "Poodle" }; // a big poodle!
printWeightInPounds(myDog);

在所有情况下严格且不允许额外属性将禁止大量合法代码。但是,选择严格在某些地方可能是件好事。有建议要有“精确类型”功能,允许您选择仅传递相同类型。它仍然是in discussion