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

TypeScript类型合并未覆盖属性?求解析怪异推断逻辑

TypeScript交叉类型未覆盖属性的原因解析

为什么交叉类型不会覆盖activities的类型?

TypeScript的交叉类型(&)对对象同名属性的处理逻辑是取类型交集,而非直接覆盖。

在你的代码中:

type Activity = { a: number };
type Options = { activities: Activity[] }

const fun = (options: Options & { activities: Array<{ b: number }> }) => {
    return options.activities.map(item => item.b)
}

Options & { activities: Array<{ b: number }> }这个交叉类型中,activities的实际类型是Activity[] & { b: number }[],等价于(Activity & { b: number })[]——也就是说,activities数组的每个元素必须同时满足{ a: number }和{ b: number }两个类型。

你看到item被推断为{ a: number },本质是TypeScript在类型检查时优先提示基础类型的属性,但实际上item的类型是两者的交集。如果尝试传入仅包含b属性的数组元素,TypeScript会直接报错,因为不满足Activity[]的要求。

为什么Omit<>能解决问题?

Omit<Options, 'activities'>的作用是移除Options类型中指定的activities属性,之后再与{ activities: Array<{ b: number }> }交叉,就不会出现同名属性的类型交集问题。

替换后的类型Omit<Options, 'activities'> & { activities: Array<{ b: number }> },本质是一个全新的对象类型:它保留了Options中除activities外的所有属性,同时将activities的类型完全替换为{ b: number }[],这就符合你原本期望的“覆盖”效果。

两种写法的差异对比

  • 交叉类型写法:要求传入的activities数组元素必须同时拥有a和b属性,否则类型不兼容。
  • Omit写法:仅要求activities数组元素拥有b属性即可,不需要包含a。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:03:26