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

TypeScript如何约束映射类型泛型参数,实现统一State入参的zipAll函数

解决方案

你遇到的问题核心是 TypeScript 无法从T extends State<S, any>[]这类泛型约束中反向推导S的类型,我们可以调整泛型设计,先接收全部入参的类型,再通过条件类型校验S的一致性,实现单个函数签名满足需求:

type State<S, A> = (s: S) => readonly [S, A];

type MapResults<T extends State<any, any>[]> = {
  [K in keyof T]: T[K] extends State<any, infer A> ? A : never
};

// 校验所有State的状态类型是否完全一致
type AllSameState<T extends State<any, any>[], S = T[number] extends State<infer _S, any> ? _S : never> =
  T extends [infer Head, ...infer Tail extends State<any, any>[]]
    ? Head extends State<S, any>
      ? AllSameState<Tail, S>
      : false
    : true

declare function zipAll<T extends State<any, any>[]>(
  ...states: AllSameState<T> extends true ? T : never[]
): T extends State<infer S, any>[] ? State<S, MapResults<T>> : never

效果验证

declare const s0: State<number, string>;
declare const s1: State<number, boolean>;
declare const sBad: State<string, symbol>;

// 正常推导:返回 State<number, [string, boolean]>
const res1 = zipAll(s0, s1); 

// 正确触发类型错误:存在状态类型不匹配的入参
const res2 = zipAll(s0, s1, sBad);

实现说明

  1. 不再将状态类型S作为显式泛型参数声明,避免 TypeScript 推导失败降级为unknown
  2. 先将所有入参的类型收集为泛型T,通过递归工具类型AllSameState遍历校验每一个入参的S类型是否完全统一
  3. 校验通过后再从T中提取统一的S类型和各个入参的返回值类型,组装为最终的聚合State类型

该方案无需函数重载、无需柯里化、无需手动传入任何类型参数,完全自动推导且类型校验严格,支持任意数量的入参。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:06:05