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

TypeScript映射类型实现类Where子句提取命令对应依赖

TypeScript 基于Handler联合生成命令-依赖映射类型实现

问题场景

在纯类型层面开展TypeScript类型编程时,给定如下基础类型定义:

type Command<Type extends string> = { type: Type };
type Handler<Type extends string, Dependencies> = (cmd: Command<Type>, deps: Dependencies) => void;

type CommandA = Command<"A">;
type CommandB = Command<"B">;

type MockServiceA = { foo: () => boolean };
type MockServiceB = { bar: () => boolean };

type HandlerA = Handler<"A", { someService: MockServiceA }>;
type HandlerB = Handler<"B", { someService: MockServiceA; anotherService: MockServiceB }>;


type HandlerSum = HandlerA | HandlerB; // 联合类型中可包含任意数量的Handler

需求说明

需要创建一个映射类型,生成由命令类型与对应依赖项构成的字典结构。
初始错误写法会返回所有依赖类型的联合结果,不符合预期:

type OnlyHalfwayThere = {
  [K in Parameters<HandlerSum>[0]["type"]]: Parameters<HandlerSum>[1]; // <--- 该写法会返回所有依赖类型的联合结果
};

需要实现类似Where子句的筛选逻辑:当Handler的第一个函数参数匹配当前遍历的键K时,提取该Handler的第二个函数参数,期望得到的结果结构如下:

type Outcome = {
  A: { someService: MockServiceA };
  B: { someService: MockServiceA; anotherService: MockServiceB };
};

正确实现

类型定义

type CommandDepsMap<THandler extends Handler<string, any>> = {
  [K in Parameters<THandler>[0]["type"]]: 
    THandler extends (cmd: Command<K>, deps: infer Deps) => void ? Deps : never;
};

// 传入Handler联合即可得到目标结构
type Result = CommandDepsMap<HandlerSum>;

实现原理

  • 核心依赖TypeScript分布式条件类型的默认行为:当条件类型的检查目标是联合类型时,TypeScript会自动遍历联合的每一个成员单独做类型匹配,最终将所有匹配结果合并为新的联合类型
  • 遍历每个命令类型K时,将传入的Handler联合逐个匹配(cmd: Command<K>, deps: infer Deps) => void结构,匹配成功就通过infer关键字提取对应依赖类型Deps
  • 不匹配当前K的Handler分支会返回never,在类型合并时会被自动忽略,最终每个K只会对应到正确的单条依赖类型,不会出现所有依赖联合的错误结果

内容的提问来源于stack exchange,提问作者florian norbert bepunkt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:09:11