编程后端 TypeScript 开发者

在 TypeScript 中,介绍一下“交叉类型”的机制(intersection types)。如何正确使用它们以及可能遇到哪些陷阱?

用 Hintsage AI 助手通过面试

回答

交叉类型(&, intersection types)允许将多个类型合并为一个,具有所有合并类型的属性。

示例:

type Person = { name: string }; type Worker = { job: string }; type WorkingPerson = Person & Worker; // { name: string; job: string } const wp: WorkingPerson = { name: "Leo", job: "Dev" };

这在组合可扩展的合同和从原始类型构建复杂类型时非常方便。

然而,如果交叉了不兼容的类型(例如,type A = { foo: string }type B = { foo: number }),就会得到一个无法初始化的类型。

不正确交叉的示例:

type A = { foo: string }; type B = { foo: number }; type C = A & B; // C = { foo: never }

陷阱性问题

如果交叉两个类型,它们有相同字段但具有不兼容的数据类型,会发生什么?

回答: 将得到一个类型为 never 的字段,因为值不能同时是字符串和数字。这样的类型是无法有效实现的。

type T1 = { id: string }; type T2 = { id: number }; type T3 = T1 & T2; // { id: never }

由于对主题细微差别不了解而产生的真实错误示例


故事

在项目中交叉了来自不同库的类型,未注意到存在相同字段但类型不同。结果得到一个意外的“无法实现”(never)类型,导致无法创建有效的对象以传递到 API。


故事

开发者需要“粘合” DTO 和域实体的类型。在交叉中,出现了两个不兼容的属性,尝试使用生成的类型会导致模糊的编译错误。开发者在调试上花了时间,才明白原因。


故事

在一个微服务中,声明了一个交叉类型来描述请求体。由于 API 的更改,一个属性获得了不同的类型,并且新更改没有立即导致编译错误—问题只在部署后的运行时出现。