能否在TypeScript接口上实现“内连接(inner join)”操作?
实现TypeScript类型的「内连接」(提取共有属性)
当然可以实现你想要的效果!你说的「内连接」本质就是提取两个类型的共有属性,在TypeScript里完全可以通过自定义泛型工具类型来做到,而且正如你所说,这种工具在泛型场景下实用性拉满。
先回顾一下你提到的交叉类型:
interface First { a: string; b: number; } interface Second { b: number; c: Date; } // 交叉类型合并所有属性 type Combined = First & Second; // {a: string, b: number, c: Date}
如果只想要两个类型共有的属性,我们可以写一个泛型工具类型来实现:
基础实现方案
// 定义泛型工具,提取T和U的共有属性 type Intersection<T, U> = { [K in Extract<keyof T, keyof U>]: T[K] }; // 使用示例 type FirstSecond = Intersection<First, Second>; // 最终类型:{ b: number }
原理说明
keyof T和keyof U分别获取两个接口的所有属性名集合Extract<keyof T, keyof U>从T的属性名中提取出和U共有的部分(也就是属性名的交集)- 最后通过映射类型,把这些共有属性名对应到原类型中的属性类型,得到只包含共有属性的新类型
严格版实现(校验属性类型一致性)
如果需要确保两个类型中共有属性的类型完全一致(避免出现比如First的b是number,Second的b是string这种不兼容的情况),可以给工具类型加上类型校验:
type StrictIntersection<T, U> = { [K in Extract<keyof T, keyof U>]: T[K] extends U[K] ? U[K] extends T[K] ? T[K] // 类型完全一致时保留 : never // 类型不一致时设为never : never }; // 测试:如果两个类型的共有属性类型不一致 interface Third { b: string; c: Date; } type FirstThird = StrictIntersection<First, Third>; // 最终类型:{ b: never },提示属性类型不兼容
内容的提问来源于stack exchange,提问作者ysfaran
相关产品推荐
相关产品推荐

