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

TypeScript中Interface与Type的属性值交并集疑问解析

TypeScript交叉类型与联合类型疑惑解答

1. 交叉类型Person & Lifespan为何不是never?取值是什么?

先明确前提:假设我们定义的两个接口无冲突属性(无同名但类型不兼容的字段),比如:

interface Person {
  name: string;
  age: number;
}

interface Lifespan {
  birth: Date;
  death?: Date;
}

为什么不是never类型?

never是没有任何值能满足的类型,而交叉类型&的本质是取两个类型「值的集合的交集」——不是合并接口属性后找冲突,而是看是否存在值能同时符合两个类型的要求。只要两个类型的取值集合有重叠(存在同时满足两个接口的对象),交叉类型就不会是never。

只有当两个类型存在同名且类型不兼容的属性时,交叉类型才会变成never。比如Person的age是number,Lifespan的age是string,交叉后age的类型是number & string(没有值能同时是数字和字符串),整个交叉类型就会是never。

该类型的取值是什么?

所有同时具备两个接口所有必填属性的对象,还可包含可选属性。比如:

const validExample: Person & Lifespan = {
  name: "Alice",
  age: 30,
  birth: new Date(1993, 0, 1),
  death: new Date(2093, 0, 1) // 可选字段可加可不加
};

怎么理解“类型操作针对值的集合而非接口属性”?

把每个TypeScript类型看成一个“池子”:

  • Person池子里装着所有有name(字符串)和age(数字)的对象
  • Lifespan池子里装着所有有birth(Date)、可选death(Date)的对象

类型操作(如&或|)直接对这些“池子”做集合运算,而非修改接口定义。交叉类型&就是取两个池子的重叠部分——同时在两个池子里的对象,也就是同时符合两个接口的对象;不是把两个接口的属性拼在一起后检查冲突(除非属性本身类型冲突)。

2. 联合类型Person | Lifespan的可赋值取值有哪些?

联合类型|是取两个类型「值的集合的并集」,只要符合其中一个接口的要求即可,具体分三类:

  • 仅符合Person的对象:有name和age字段,不需要birth或death,比如:
    const onlyPerson: Person | Lifespan = { name: "Bob", age: 25 };
    
  • 仅符合Lifespan的对象:有birth字段,可选death,不需要name或age,比如:
    const onlyLifespan: Person | Lifespan = { birth: new Date(2000, 5, 10) };
    
  • 同时符合两个接口的对象:也就是前面交叉类型里的取值,也可以赋值给联合类型(因为它同时满足两个类型,自然属于并集的一部分),比如之前的validExample也能赋值给Person | Lifespan。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:42:27