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

TypeScript如何为接受扁平可变参数对的函数定义类型?

实现扁平参数的函数签名类型定义

1. 简单Pair类型场景

对于简单的Pair类型:

type Pair = { type: string, value: number };

我们可以通过可变元组类型和递归类型实现扁平参数的约束,确保参数以type+value的成对形式传入,同时生成对应的Pair[]返回类型。

类型定义:

// 递归将多组 [string, number] 转为扁平参数列表
type FlattenedPairs<T extends any[] = []> = 
  T extends [infer H, ...infer R] 
    ? H extends [string, number] 
      ? [...H, ...FlattenedPairs<R>] 
      : never
    : [];

// 从扁平参数推导返回的Pair数组类型
type PairsFromFlattened<T extends any[]> = 
  T extends [string, number, ...infer R] 
    ? [Pair, ...PairsFromFlattened<R>] 
    : [];

// 函数签名
declare function makePairs<T extends [string, number, ...any[]]>(
  ...args: FlattenedPairs<T>
): PairsFromFlattened<FlattenedPairs<T>>;

使用示例:

// 合法调用:参数成对且类型匹配
const pairs = makePairs("a", 1, "b", 2); // 返回类型为 Pair[]
// 错误调用:参数个数奇数或类型不匹配
makePairs("a", "b", 2); // 类型报错
makePairs("a", 1, 2); // 类型报错

2. 复杂联合Pair类型场景

已知联合类型Pair及辅助类型PairType、PairOfType、ValueOfType、PairTuple(基于常规场景推导辅助类型定义,若你的实际定义不同可微调):

type StrPair = { type: 's', value: string };
type IntPair = { type: 'i', value: number };
type BoolPair = { type: 'b', value: boolean };
type Pair = StrPair | IntPair | BoolPair;

// 辅助类型定义
type PairType = Pair['type'];
type PairOfType<T extends PairType> = Extract<Pair, { type: T }>;
type ValueOfType<T extends PairType> = PairOfType<T>['value'];
type PairTuple = [PairType, ValueOfType<PairType>];

我们需要让makePairs接受多个展开的PairTuple作为扁平参数,同时严格约束每组type与对应value的类型匹配。

类型定义:

// 递归验证扁平参数,确保每组type和value类型严格对应
type FlattenedUnionPairs<T extends any[] = []> = 
  T extends [infer Type extends PairType, ...infer Rest]
    ? [Type, ValueOfType<Type>, ...FlattenedUnionPairs<Rest>]
    : [];

// 从扁平参数推导返回的联合Pair数组类型
type UnionPairsFromFlattened<T extends any[]> = 
  T extends [infer Type extends PairType, ValueOfType<Type>, ...infer Rest]
    ? [PairOfType<Type>, ...UnionPairsFromFlattened<Rest>]
    : [];

// 函数签名
declare function makePairs<T extends PairType[]>(
  ...args: FlattenedUnionPairs<T>
): UnionPairsFromFlattened<FlattenedUnionPairs<T>>;

使用示例:

// 合法调用:每组type和value类型严格匹配
const pairs = makePairs('s', 'hello', 'i', 123, 'b', true); 
// 返回类型为 [StrPair, IntPair, BoolPair]

// 错误调用:type和value类型不匹配
makePairs('s', 123); // 类型报错('s'对应value应为string)
makePairs('i', 'abc'); // 类型报错('i'对应value应为number)

关键说明:

  • 两种场景均利用TypeScript的递归条件类型和可变元组类型实现扁平参数的类型约束。
  • 复杂联合场景中,通过PairType与ValueOfType的关联,强制type和value的类型匹配,避免不兼容的调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:25:12