【问题标题】:Why typescript do not complain when i pass const with extra key in function为什么当我在函数中传递带有额外键的 const 时打字稿不抱怨
【发布时间】:2020-06-13 08:41:52
【问题描述】:

我想知道为什么当我在函数中传递带有额外键的 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

【问题讨论】:

标签: typescript


【解决方案1】:

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

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

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

类型检查器检查对 printLabel 的调用。打印标签 函数有一个参数,要求传递的对象 in 有一个称为字符串类型标签的属性。注意我们的对象 实际上有比这更多的属性,但编译器只检查 至少存在所需的并且与类型匹配 必需的。在某些情况下,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 的立场是可能存在错误 这段代码。对象文字得到特殊处理并经历过多 将它们分配给其他变量或传递时的属性检查 他们作为论据。如果一个对象字面量有任何属性 “target type”没有,会报错:

// 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;
}

【讨论】:

    猜你喜欢
    • 2022-10-15
    • 2016-05-22
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2021-04-26
    • 2019-06-13
    • 1970-01-01
    • 2016-05-17
    相关资源
    最近更新 更多