gpt4 book ai didi

分配对象时,TypeScript 接口(interface)不强制执行属性

转载 作者:行者123 更新时间:2023-12-04 12:28:48 26 4
gpt4 key购买 nike

我很难理解 TypeScript 的接口(interface)规则。我知道以下代码块会引发错误,因为 id接口(interface)中未定义属性:

interface Person {
name: string;
}

let person: Person = { name: 'Jack', id: 209 }
但是为什么 TypeScript 不是 如果我尝试添加 id 会抛出错误属性通过分配另一个对象?像这样例如:
const samePerson = { name: 'Jack', id: 209 };
person = samePerson;
person对象最终得到 id属性,即使它没有在接口(interface)中定义。

最佳答案

对象类型通常是开放和可扩展的,并允许额外的属性......
TypeScript 中的对象类型通常是开放和可扩展的。对象是 Person当且仅当它有 name类型的属性 string .这样的对象可能有额外的属性,但它仍然是 Person .这非常有用,并且允许接口(interface)扩展形成类型层次结构:

interface AgedPerson extends Person {
age: number;
}

const agedPerson: AgedPerson = { name: "Alice", age: 35 };
const stillAPerson: Person = agedPerson; // okay
因为 TypeScript 有一个 structural type system ,您实际上不必为 AgedPerson 声明接口(interface)因为它被视为 Person 的子类型:
const undeclaredButStillAgedPerson = { name: "Bob", age: 40 };
const andStillAPersonToo: Person = undeclaredButStillAgedPerson; // okay
这里 undeclaredButStillAgedPerson类型为 {name: string, age: number} ,相当于 AgedPerson ,以及对 Person 的后续赋值出于同样的原因。

尽管开放/可扩展类型很有用,但它可能会令人困惑,有时也是不想要的。在 microsoft/TypeScript#12936 有一个长期开放的请求让 TypeScript 支持所谓的精确类型,例如 Exact<Person>只允许有 name属性(property),没有别的。安 AgedPerson将是 Person但不是 Exact<Person> .目前没有对此类确切类型的直接支持。

...但是对象字面量确实经过了过多的属性检查。
回溯:TypeScript 中的对象类型一般都是开放的。但是在一种情况下,对象将被视为其类型是精确的。这是当您分配 object literal 时到变量或将其作为参数传递。
对象文字得到特殊处理并接受 excess property checking首次分配给变量或作为函数参数传递时。如果对象字面量具有在预期类型中未知的属性,则会出现错误。像这样:
let person: Person = { name: 'Jack', id: 209 }; // error!
// -------------------------------> ~~~~~~~
// Object literal may only specify known properties,
// and 'id' does not exist in type 'Person'.
即使 {name: "Jack", id: 209}Person根据原始定义,它不是 Exact<Person> ,所以我们得到一个错误。请注意,该错误特别提到了“对象文字”。

将此与以下内容进行对比,其中没有错误:
const samePerson = { name: 'Jack', id: 209 }; // okay
person = samePerson; // okay
将对象字面量赋值给 samePerson没有错误,因为 samePerson的类型被推断为类型
/* const samePerson: {
name: string;
id: number;
} */
那里没有多余的属性(property)。 samePerson的后续赋值至 person也成功了,因为 samePerson不是对象字面量,因此不适用额外的属性检查。

Playground link to code

关于分配对象时,TypeScript 接口(interface)不强制执行属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68478462/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com