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

如何从函数交叉类型中根据首个参数值提取参数类型?

从函数交叉类型中提取指定首个参数对应的参数类型

我尝试从函数交叉类型中,提取首个参数值为指定内容的对应参数类型,示例代码如下:

type Test = ((evt: 'confirmed', args_0: { overwrite: boolean }) => void) & ((evt: 'canceled') => void);

type ExtractArg<T, E> = T extends (evt: E, args: infer P) => void ? P : never;
type ExtractConfirmedArgs<T> = T extends (evt: 'confirmed', arg: infer U) => void ? U : never;

type EventParameters<T, E> = T extends (evt: infer TE, ...args: infer Args) => void ? (TE extends E ? Args : never) : never;

// 无法正常工作
type ConfirmedParameters = EventParameters<Test, 'confirmed'>[0];
// 同样无法正常工作
type P = ExtractArg<Test, 'confirmed'>;

type AnotherTry = ExtractConfirmedArgs<Test>;

我期望得到类型ConfirmedArgs = { overwrite: boolean },但上述尝试均失败。想请教是操作有误,还是仅能在联合类型中实现该功能?使用的TypeScript版本为5.4.5。


问题原因

函数交叉类型在条件类型中会被当作整体进行兼容性检查,只有当交叉类型的所有分支都匹配目标函数签名时,条件才会成立。你的Test类型包含两个函数分支,第二个分支(evt: 'canceled') => void不匹配(evt: 'confirmed', arg: infer U) => void签名,因此所有尝试都返回never。

解决方案

通过T extends any ? ...的写法强制触发分布式条件类型,将交叉类型的每个分支单独代入条件判断,相当于把交叉类型“展开”为联合类型处理:

通用提取单个参数类型

type ExtractArg<T, E> = T extends any ? (T extends (evt: E, args: infer P) => void ? P : never) : never;

type ConfirmedArgs = ExtractArg<Test, 'confirmed'>; // { overwrite: boolean }

针对特定事件的提取

type ExtractConfirmedArgs<T> = T extends any ? (T extends (evt: 'confirmed', arg: infer U) => void ? U : never) : never;

type ConfirmedArgs = ExtractConfirmedArgs<Test>; // { overwrite: boolean }

提取完整参数数组

如果需要提取该事件对应的所有参数组成的数组类型:

type EventParameters<T, E> = T extends any ? (T extends (evt: infer TE, ...args: infer Args) => void ? (TE extends E ? Args : never) : never) : never;

type ConfirmedParameters = EventParameters<Test, 'confirmed'>[0]; // { overwrite: boolean }

原理说明

T extends any ? ...会遍历交叉类型的每个分支,对每个分支单独执行后续的条件判断。只有匹配目标签名的分支会返回提取到的类型,不匹配的分支返回never,最终结果为所有有效提取结果的联合(这里仅一个有效结果,即目标类型)。

内容的提问来源于stack exchange,提问作者Maksym

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:34:54