如何调整arrayWrapper函数重载,实现泛型自动类型推断?
问题
刚开始使用函数重载,定义了如下带有重载的arrayWrapper函数,但泛型类型<T>的推断时常不符合预期:
function arrayWrapper<T>(input: T): T[]; function arrayWrapper<T>(input: T[]): T[]; function arrayWrapper<T>(input: T | T[]): T[] { if (input instanceof Array) { return input; } return [input]; }
例如以下代码:
function arrayWrapperExample(): string[] { return arrayWrapper(['hello']); // 此处报错 }
会出现类型推断错误:
Type 'string[][]' is not assignable to type 'string[]'. Type 'string[]' is not assignable to type 'string'.ts(2322)
显式指定泛型类型arrayWrapper<string>(['hello'])可解决报错,但因函数返回类型已声明,此操作冗余。请问如何调整arrayWrapper的重载声明,无需重复指定泛型类型?
解决方案
问题根源在于重载的泛型匹配逻辑:当传入['hello']时,TypeScript会优先匹配第一个重载签名arrayWrapper<T>(input: T): T[],此时T被推断为string[],返回类型变成string[][],与预期的string[]冲突。
调整重载的泛型约束,让数组输入的签名能正确推导元素类型即可解决问题,修改后的代码如下:
// 处理非数组输入:输入非数组类型T,返回T[] function arrayWrapper<T>(input: Exclude<T, any[]>): T[]; // 处理数组输入:输入T[],返回T[] function arrayWrapper<T>(input: T[]): T[]; function arrayWrapper<T>(input: T | T[]): T[] { if (input instanceof Array) { return input; } return [input]; }
关键说明
- 第一个重载通过
Exclude<T, any[]>限制输入不能是数组类型,确保只有非数组值才会匹配此签名,避免数组输入被错误归类。 - 第二个重载明确接收
T[],此时TypeScript会自动将数组的元素类型推断为T,返回类型自然为T[],与arrayWrapperExample声明的返回类型string[]完美匹配。
现在调用arrayWrapper(['hello'])时,TypeScript会正确匹配第二个重载,自动推断T为string,返回string[],无需手动指定泛型类型。
内容的提问来源于stack exchange,提问作者Cameron Hudson
相关产品推荐
相关产品推荐

