为强类型元组实现递归类型推断的问题求助
解决TypeScript元组类型递归推断的返回值类型错误
首先修正你代码里MyType的语法错误(缺少=):
type MyType<V> = { value: V }
你遇到的问题是递归函数返回空数组时,TypeScript编译器无法自动推断[]与InferRecursive<T>类型匹配。下面提供两种解决思路:
方案一:修复递归实现的类型错误
保留你原有的递归类型逻辑,通过类型断言明确空数组的类型匹配,同时优化泛型约束提升推断稳定性:
type MyType<V> = { value: V } type Infer<T> = T extends MyType<infer V> ? V : never; type InferRecursive<T extends readonly MyType<any>[]> = T extends [] ? [] : T extends [infer U, ...infer URem] ? [Infer<U>, ...InferRecursive<URem>] : never; function getValue<T extends MyType<any>>(obj: T): Infer<T> { return obj.value; } function getValues<T extends readonly MyType<any>[]>(...objs: T): InferRecursive<T> { if (objs.length === 0) { // 用类型断言告知编译器空数组符合返回值类型 return [] as InferRecursive<T>; } const [next, ...rest] = objs; return [getValue(next), ...getValues(...rest)] as InferRecursive<T>; } // 测试验证 const obj1: MyType<number> = { value: 1 }; const obj2: MyType<string> = { value: "hello" }; const obj3: MyType<Date> = { value: new Date() }; const values = getValues(obj1, obj2, obj3); // TypeScript自动推断values类型为 [number, string, Date]
方案二:用映射类型替代递归(更简洁)
利用TypeScript的元组索引映射特性,无需递归类型定义即可实现精准的类型推断:
type MyType<V> = { value: V } // 通过元组索引映射直接推导value类型组成的元组 type ValueTuple<T extends readonly MyType<any>[]> = { [K in keyof T]: T[K] extends MyType<infer V> ? V : never; } function getValues<T extends readonly MyType<any>[]>(...objs: T): ValueTuple<T> { // 用类型断言让map的返回值匹配目标元组类型 return objs.map(obj => obj.value) as ValueTuple<T>; } // 测试验证 const obj1 = { value: 1 } as const; const obj2 = { value: "hello" } as const; const obj3 = { value: new Date() }; const values = getValues(obj1, obj2, obj3); // TypeScript自动推断values类型为 [1, "hello", Date]
关键说明
- 类型断言:在两种方案中,类型断言都是为了让编译器确认返回值与定义的类型完全匹配,解决动态分支下的类型推断盲区。
- readonly约束:给泛型参数添加
readonly可以让元组类型推断更稳定,同时支持只读元组的输入场景。 - 映射类型优势:相比递归类型,元组索引映射写法更简洁,TypeScript对这种模式的类型推断支持更成熟。
内容的提问来源于stack exchange,提问作者narangkay
相关产品推荐
相关产品推荐

