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

如何改写TypeScript的SchemaParameters类型以支持联合类型的参数提取?

解决SchemaParameters处理联合类型的问题

你的问题核心在于条件类型没有对联合类型的分支进行分布式处理。原来的实现用[T] extends [...]把类型包裹在元组里,这会阻止TypeScript的分布式条件类型特性——本来当条件类型的检查目标是联合类型时,TS会自动拆分每个分支单独处理,再把结果合并,但元组包裹后整个联合类型被当成单一整体,导致推断不符合预期。

解决方案:改用分布式条件类型

去掉元组的包裹,直接让T作为条件类型的检查目标,这样每个联合分支会被单独处理,结果自动合并为联合类型:

export type SchemaParameters<T> = 
  // 处理函数类型:提取参数元组
  T extends (...args: infer U) => any 
    ? U 
    // 处理void类型:返回空元组
    : T extends void 
      ? [] 
      // 处理普通类型:返回单元素元组
      : [T];

验证各个场景

现在这个实现能正确处理你提到的所有情况:

  1. 单个属性的原有逻辑保持正常:
const fromConstant: SchemaParameters<Schema['string']> = ['lorem ipsum']; // 类型为 [string] ✔️
const fromFunction: SchemaParameters<Schema['stringReceiver']> = ['lorem ipsum 2']; // 类型为 [string] ✔️
  1. 处理num | stringReceiver联合类型:
const value1: SchemaParameters<Schema['num' | 'stringReceiver']> = ['lorem ipsum']; // 类型为 [number] | [string] ✔️
const value2: SchemaParameters<Schema['num' | 'stringReceiver']> = [123]; // 同样符合类型 ✔️
  1. 处理两个接收器的联合类型:
const receiverValue: SchemaParameters<Schema['numReceiver' | 'stringReceiver']> = [123]; // 类型为 [number] | [string] ✔️
const receiverValue2: SchemaParameters<Schema['numReceiver' | 'stringReceiver']> = ['hello']; // 同样符合类型 ✔️

可选:合并为单元素联合元组

如果你确实期望结果是[number | string](而非元组的联合),可以进一步调整实现,提取每个分支的元素类型再合并:

export type SchemaParameters<T> = 
  T extends void 
    ? [] 
    : [
        T extends (...args: infer U) => any 
          ? U[number] 
          : T
      ];

这个版本会把所有分支的结果合并到单个元组中,比如SchemaParameters<Schema['num' | 'stringReceiver']>会解析为[number | string]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:22:50