递归函数参数为数组时的正确返回类型问题
解决TypeScript递归函数返回类型不匹配问题
你的问题出在返回类型的定义上:当前用的联合类型(number | undefined) | (number | undefined)[]无法让TypeScript正确推断输入与输出的对应关系——当输入是数组时,TypeScript会误以为递归调用可能返回数组,导致map后的结果类型变成包含数组的嵌套类型,从而触发类型错误。
正确写法1:使用泛型关联输入输出类型
通过泛型让函数的返回类型严格匹配输入类型:
#foo<T extends number | number[]>(bar: T): T extends number ? number | undefined : (number | undefined)[] { if (Array.isArray(bar)) { return bar.map(this.#foo, this) as T extends number[] ? (number | undefined)[] : never; } if (bar <= 10 ) { return 20 as T extends number ? number | undefined : never; } return undefined as T extends number ? number | undefined : never; }
解释
- 泛型约束:
T extends number | number[]限定输入只能是数字或数字数组 - 条件类型返回值:
T extends number ? number | undefined : (number | undefined)[]明确:输入是number时返回number | undefined,输入是number[]时返回(number | undefined)[] - 类型断言:分支中用
as告诉编译器当前返回类型符合条件类型的结果,解决TypeScript自动推断的局限性
正确写法2:利用函数重载简化实现
如果觉得泛型条件类型太复杂,用函数重载可以更直观地定义输入输出对应关系:
#foo(bar: number): number | undefined; #foo(bar: number[]): (number | undefined)[]; #foo(bar: number | number[]): number | undefined | (number | undefined)[] { if (Array.isArray(bar)) { return bar.map(this.#foo, this); } if (bar <= 10 ) { return 20; } return undefined; }
函数重载会明确告知编译器不同输入对应的返回类型,TypeScript能正确识别map后的结果类型,不会再出现嵌套类型的错误。
内容的提问来源于stack exchange,提问作者alexojegu
相关产品推荐
相关产品推荐

