如何在TypeScript中合并不同类型的数组字段类型?
解决TypeScript中合并含同名数组字段的类型问题
直接使用交叉类型A & B无法达到你想要的效果,因为交叉后的arr字段是两个数组类型的交叉(({ foo: number }[]) & ({ bar: string }[])),这种类型在调用数组方法(比如filter)时,TypeScript的类型推断会出现异常——回调函数的参数类型会被限制为其中一个数组的元素类型,导致无法访问另一个类型的属性。
要实现合并数组元素类型的需求,你需要自定义一个工具类型来处理同名数组字段的合并逻辑:
type A = { arr: { foo: number }[] other_field: number; } type B = { arr: { bar: string }[] another_field: string; } // 自定义合并类型:处理同名数组字段的元素合并 type Merge<T, U> = { [K in keyof T | keyof U]: K extends keyof T ? K extends keyof U ? // 若两个字段都是数组,合并元素类型 T[K] extends Array<infer TEl> ? U[K] extends Array<infer UEl> ? Array<TEl & UEl> : T[K] & U[K] : T[K] & U[K] : T[K] : U[K] }; // 使用自定义合并类型得到目标类型 type C = Merge<A, B> // 测试代码 const array: C = { arr: [], other_field: 1, another_field: "test" } console.log(array.arr[0].foo) // 正常访问 console.log(array.arr[0].bar) // 正常访问 array.arr.filter(n => n.foo) // 正常执行 array.arr.filter(n => n.bar) // 正常执行,不再报错
原理说明
- 这个
Merge工具类型会遍历两个输入类型的所有键:- 如果键同时存在于两个类型中,且两个字段都是数组,则将数组的元素类型交叉合并,生成新的数组类型;
- 其他情况(非数组字段或仅存在于单个类型的字段)则沿用交叉类型的默认行为,合并字段类型。
内容的提问来源于stack exchange,提问作者jayatubi
相关产品推荐
相关产品推荐

