You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript对象展开解构存疑:为何允许多余字段?

为什么对象展开赋值能通过TypeScript类型检查,直接字面量赋值却不行?

先看你提供的代码:

interface Person {
    name: string;
    age: number
}

interface UnknownPerson {
    age: number;
}

let me: Person = {
    name: "vilgeforc5",
    age: 19
}

// 能通过类型检查
let anotherPerson: UnknownPerson = {
    ...me
}
console.log(anotherPerson.name) /* TypeScript报错,但运行时能正常输出 */

// 触发TypeScript错误
let anotherPerson2: UnknownPerson = {
    name: "vilgeforc5",
    age: 19
}

核心原因:TypeScript的「额外属性检查」机制

这是TypeScript的正常行为,和编译选项无关,差异来自两种赋值场景的类型检查逻辑不同:

  • 直接字面量赋值时的严格检查
    当你直接把对象字面量赋值给类型变量时,TypeScript会启动「额外属性检查」——它会严格校验字面量的所有属性是否都被目标类型定义,不允许存在未声明的额外属性。所以anotherPerson2里的name属性不在UnknownPerson的定义中,直接触发错误。

  • 变量展开赋值时的结构化类型兼容
    而me是已经被标注为Person类型的变量,TypeScript这里会套用结构化类型系统的兼容规则:只要源类型包含目标类型的所有必填属性,源类型就可以赋值给目标类型。Person包含UnknownPerson要求的age属性,因此Person是UnknownPerson的兼容子类型,展开me后的对象可以赋值给anotherPerson。

    注意:运行时anotherPerson确实会保留name属性,但TypeScript的类型系统会认为它是UnknownPerson类型,所以访问anotherPerson.name会触发类型错误,这是类型系统的静态约束,和运行时行为无关。

内容的提问来源于stack exchange,提问作者Boris Borais

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:34:58