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

Jal*_*Jal 3 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"});
Run Code Online (Sandbox Code Playgroud)

差异的原因是什么?

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

JKi*_*ian 5

TypeScript 仅检查声明对象文字的位置是否有多余的属性(如您在问题中所述)。TypeScript 文档描述了此检查:(也可以在此处随意查看完整规范。)

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);
Run Code Online (Sandbox Code Playgroud)

在所有情况下严格且不允许额外的属性将不允许大量合法代码。然而,在某些地方,严格选择加入可能是一件好事。有人建议拥有“精确类型”功能,该功能允许您选择仅传递相同的类型。但它仍在讨论中