Typescript如何从传入泛型参数推断并返回有序的对应内部类型
解决方案
核心通过TS可变元组泛型+函数重载实现两种调用形式的兼容,利用映射类型保留入参的元组顺序,避免类型合并为联合数组。
完整类型实现
// 先定义你需要的Outer接口 interface Outer<V> { data: V }; // 重载1:支持多参数直接传入形式:foo(outerA, outerB) declare function foo<T extends Outer<any>[]>(...args: T): { [K in keyof T]: T[K] extends Outer<infer V> ? V : never }; // 重载2:支持单个数组传入形式:foo([outerA, outerB]) declare function foo<T extends Outer<any>[]>(args: T): { [K in keyof T]: T[K] extends Outer<infer V> ? V : never };
效果验证
基础示例测试
const [d1, d2] = foo([{data: {a: {x: "a"}}}, {data: {b: "b"}}]); console.log(d1.a.x); // d1类型被正确识别为 {a: {x: "a"}} console.log(d2.b); // d2类型被正确识别为 {b: "b"}
顺序保留测试
type A = {a: string}; type B = {b: number}; const a: Outer<A> = {data: {a: '测试'}}; const b: Outer<B> = {data: {b: 123}}; const result = foo([b, a]); // result类型被正确推导为 [B, A],严格保留入参顺序
原代码问题说明
你之前的写法没有将入参约束为元组类型,TS默认会把数组泛型推导为普通数组,所有元素类型合并为联合类型。使用T extends Outer<any>[]配合keyof T遍历映射时,TS会自动识别传入的元组结构,单独推导每个位置的类型,不会合并为联合。
注:该特性需要TS版本≥4.0,对应可变元组泛型支持。
内容的提问来源于stack exchange,提问作者simPod
相关产品推荐
相关产品推荐

