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

从函数数组推导参数类型时结果为never的问题求助

从函数数组推导参数类型时结果为never的问题求助

我最近在写TypeScript的时候碰到了个头疼的问题——想从一个函数数组里提取所有函数的第一个参数类型,结果用infer推出来的类型居然是never,试了好多次都没搞明白问题出在哪。

先给大家看一下我的代码:
首先定义了这样一个函数数组类型:

type ArrayOfItem = [
  (a: "type_a") => {},
  (a: "type_b") => {},
];

我想用infer把里面所有a的类型提取出来,于是写了这段类型推断代码:

type TypeOfAllData = ArrayOfItem[number] extends (a: infer T) => void ? T : never;

本以为能得到"type_a" | "type_b",结果TypeOfAllData的类型却是never,这可把我整懵了。有没有懂行的朋友能帮我分析下原因,再给个解决办法呀?


问题根源分析

其实这是TypeScript联合类型条件推断的一个特性:当你在逆变位置(比如函数的参数位置)做infer推断时,TypeScript会取各个分支推断结果的交集,而不是我们预期的并集。

这里ArrayOfItem[number]本质是一个联合类型:((a: "type_a") => {}) | ((a: "type_b") => {})。当直接对这个联合类型做extends (a: infer T) => void的推断时,TypeScript会试图找一个能同时满足两个函数参数要求的T——也就是"type_a"和"type_b"的交集,可这两个是完全不同的字面量类型,它们的交集自然就是never了。

解决办法

要拿到我们想要的联合类型,就得用分布式条件类型——让TypeScript把联合类型拆成单个成员分别处理,再把结果合并起来。只需要把推断逻辑改成泛型形式就行:

// 先定义一个泛型类型,专门处理单个函数类型的参数提取
type ExtractParam<T> = T extends (a: infer U) => void ? U : never;

// 再用这个泛型处理函数联合类型
type TypeOfAllData = ExtractParam<ArrayOfItem[number]>; // 结果为 "type_a" | "type_b"

泛型参数T会自动遍历联合类型的每个成员,分别推断出"type_a"和"type_b",最后把这两个结果合并成联合类型,这样就得到我们预期的结果啦!

备注:内容来源于stack exchange,提问作者Ali Akbar Azizi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:43:10