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

合并含同名属性的TypeScript类型后,为何属性赋值结果不一致?

为什么TypeScript交叉类型的属性直接赋值正常,但索引访问该属性时赋值报错?

先看你的代码示例:

type a = {
    a: number
    b: {d: string}[]
}
type b = {
    c : string
    b: {f: number}[]
}

type l = a & b

// 正常通过类型检查
const ab: l = {a: 1, c: '', b: [{d: '', f:1}]}

// 触发类型错误
const ac: l['b'] = [{ d: '', f: 1}]

报错信息:

Type '{ d: string; f: number; }[]' is not assignable to type '{ d: string; }[] & { f: number; }[]'.
  Types of property 'pop' are incompatible.
    Type '() => { d: string; f: number; }' is not assignable to type '(() => { d: string; }) & (() => { f: number; })'.
      Type '() => { d: string; f: number; }' is not assignable to type '() => { d: string; }'.
        Type '{ d: string; f: number; }' is not assignable to type '{ d: string; }'.
          Object literal may only specify known properties, and 'f' does not exist in type '{ d: string; }'.

核心原因:交叉类型的属性推断 vs 索引访问的严格类型解析

1. 直接赋值交叉类型对象时的类型合并

当你给l类型的变量ab赋值对象字面量时,TypeScript会进行上下文类型推断,对交叉类型的属性做智能合并:

  • l是a & b,它的b属性会被自动解析为两个数组元素类型的交叉,也就是({d: string} & {f: number})[],等同于{d: string, f: number}[]。
  • 因此,数组元素同时包含d和f属性完全符合合并后的类型,不会触发对象字面量的额外属性检查。

2. 索引访问l['b']的严格类型规则

当你直接通过l['b']获取类型时,TypeScript会严格按照交叉类型的索引访问逻辑,返回a['b'] & b['b'],也就是{d: string}[] & {f: number}[]。这个类型的含义是:

  • 该数组必须同时满足{d: string}[]和{f: number}[]的所有约束,包括数组方法的签名兼容性。
  • 当你赋值[{d: '', f:1}]时,TypeScript会先检查数组是否符合{d: string}[]:此时数组元素是对象字面量,而{d: string}类型不允许存在未声明的f属性(这是TypeScript防止拼写错误的严格检查规则),因此触发报错。
  • 另外,数组方法pop()的兼容性检查也会失败:{d: string}[] & {f: number}[]的pop()要求返回值同时满足{d: string}和{f: number},但对象字面量的额外属性f被判定为不符合{d: string}的要求。

3. 解决方法

如果你需要得到合并后的数组类型,可以手动推导元素的交叉类型:

type MergedBElement = a['b'][number] & b['b'][number];
type MergedB = MergedBElement[];

// 正常通过检查
const ac: MergedB = [{ d: '', f: 1}];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:04