You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:35:20