打字稿:为什么传递对象和作为参数分配给该对象的变量之间存在差异?

Typescript: Why is there a difference between passing an object and a variable assigned to that object as an argument?

为什么将分配给对象文字的变量作为参数传递(let x = {color: 'red', width: 200})与将对象文字作为参数传递({color: 'red', width: 200})之间存在差异?

换句话说,参数的值是相同的({color: 'red', width: 200})。
那么,为什么编译器在传递对象时进行额外检查,而在传递分配给该对象的变量时进行“常规形状”检查?

考虑函数类型签名:

type SOME_OBJECT = {
  propA: TYPE_A,
  propB: TYPE_B
}

function foo(obj: SOME_OBJECT) {
  // WILL DO SOMETHING WITH obj
}

Typescript playground

在上面的示例中,函数 foo 需要一个对象 obj,该对象具有 TYPE_A 类型的 propApropB 类型 TYPE_B。只要满足这些要求,函数 foo 就可以完成它的工作。或者至少,这是它的合同所暗示的。那么它应该超出属性检查obj参数?

现在让我们分配一个对象字面量。假设您有一个具有 可选参数 maybe.

的类型
interface SOME_OBJECT_WITH_OPTIONAL {
    color: string,
    width: number,
    maybe?: boolean
}

const x1: SOME_OBJECT_WITH_OPTIONAL = {
    color: "red",
    width: 200,
    mayeb: true      // <--- TS ERROR HERE - EXCESS PROPERTY CHECKING IS REALLY IMPORTANT
}

您发现您将 maybe 属性 拼错为 mayeb。由于过多的 属性 检查,Typescript 会警告您犯了那个错误。如果不按原样处理,您能想象痛苦吗?在我们的示例中,没有 属性 会丢失,因为 maybe 是可选的,因此允许丢失。您不会收到任何错误或警告。

期望 SOME_OBJECT_WITH_OBJECT 类型的 obj 的函数仍然不会介意。因为所有必需的属性 colorwidth 都存在。

您可以在此处阅读有关此主题的更多信息:

Typescrip Docs - Excess Property Checks

Medium - Introduction to TypeScript Interfaces — Object Literals and Function Types