为何TypeScript会将函数内部的参数类型标记为never?
问题解析与解决
为什么item会被标记为never类型?
当你用联合类型定义函数签名时,TypeScript在校验函数实现逻辑时,会对所有重载的参数类型取交集:
arr的类型是string[]和number[]的交集,也就是never[](不存在同时属于string数组和number数组的类型)- 对应的
func参数类型是(item: string) => boolean和(item: number) => boolean的交集,即(item: never) => boolean
所以循环里的arr[i]自然会被推断为never类型。
最优解决方案:用泛型替代重载联合
用泛型定义Filter能让TypeScript正确推断类型,同时保留完整的类型安全,写法也更简洁:
type Filter = <T extends string | number>(arr: T[], f: (item: T) => boolean) => T[] let filter: Filter = (arr, func) => { let result: typeof arr = [] for (const item of arr) { if (func(item)) { result.push(item) } } return result }
兼容原重载结构的方案:显式指定类型(类型断言)
如果必须保留原有的重载签名结构,可以通过类型断言明确告诉编译器参数的可能类型:
type Filter = { (arr: string[], f: (item: string) => boolean): string[] (arr: number[], f: (item: number) => boolean): number[] } let filter: Filter = (arr: string[] | number[], func: (item: string | number) => boolean) => { let result: string[] | number[] = [] for (const item of arr) { if (func(item as string | number)) { result.push(item) } } return result as string[] | number[] }
这种方式虽然能解决类型报错,但不如泛型方案优雅,泛型能更好地维持类型一致性与自动推断能力。
内容的提问来源于stack exchange,提问作者Egor Konovalov
相关产品推荐
相关产品推荐

