当我在函数中使用额外的键传递const时,为什么打字稿不会抱怨

时间:2020-06-13 08:41:52

标签: typescript

我想知道为什么当我通过函数中的额外键传递const时,打字稿不会抱怨,而当我传递与对象相同的对象时抱怨呢?

游乐场链接here

type ArgType = {
  a: string,
  b: string,
}

var a = (arg: ArgType): void => {};

a({
  a: 'a',
  b: 'b',
  c: 'c', // error as expected - OK
})

const arg0 = {
  a: 'a',
  b: 'b',
  c: 'c',
};

a(arg0) // no error - KO

1 个答案:

答案 0 :(得分:0)

这是Typescript的设计方式,我不知道幕后的设计过程,但直接引用了Typescript文档:

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

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

类型检查器检查对printLabel的调用。打印标签 函数有一个参数,要求传递该对象 中具有称为字符串类型标签的属性。注意我们的对象 实际上具有比这更多的属性,但是编译器仅检查 至少存在所需的并与类型匹配 需要。在某些情况下,TypeScript不太宽大, 我们将稍作介绍。

但是TS编译器会对对象文字进行Excess Property Checks

在使用接口的第一个示例中,TypeScript让我们传递{size: 数;标签:字符串; }到只需要{标签的内容: 串; }

但是,将其与可选类型结合使用会导致错误 潜入。例如,以createSquare为例:

interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
    // ...
}

let mySquare = createSquare({ colour: "red", width: 100 });

请注意,给createSquare的给定参数拼写为colour 而不是color。在普通的JavaScript中,这种事情会失败

您可能会争辩说该程序的类型正确,因为宽度 属性兼容,不存在颜色属性,并且 额外的颜色属性微不足道。

但是,TypeScript的立场是可能存在错误 此代码。对象字面量会得到特殊处理并遭受过多 将它们分配给其他变量或传递时进行属性检查 他们作为论点。如果对象文字具有任何属性, 没有“目标类型”,则会出现错误:

// error: Object literal may only specify known properties, but 'colour' does not exist in type 'SquareConfig'. Did you mean to write 'color'?
let mySquare = createSquare({ colour: "red", width: 100 });

最后,有几种方法可以解决此情况:

1。。您可以使用Type Assertion

let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);

2。。您可以先将其分配给另一个变量,然后传递该变量:

let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);

3。。另一种方法可能是添加字符串索引签名,如果您确定该对象可以具有某些以特殊方式使用的额外属性:

interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}