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

如何创建TypeScript映射类型工具类型以简化重复定义?

如何用工具类型简化重复的TypeScript映射类型定义

可行的实现方案

TypeScript本身不直接支持将泛型类型(比如SomeOtherType)作为"类型构造器"传递给另一个工具类型,但可以通过函数类型模拟高阶类型的方式实现你想要的简化效果:

// 核心工具类型:将键集合K中的每个键P,应用到传入的类型构造器上
type Mapped<K extends keyof any, F> = {
  [P in K]: F extends (arg: P) => infer R ? R : never;
};

// 示例:你原本的泛型类型
type SomeOtherType<P> = { value: P };

// 简化后的映射类型定义
type SomeType<K extends string> = Mapped<K, (p: P) => SomeOtherType<P>>;

使用效果和手动写的映射类型完全一致:

// 得到 { a: { value: "a" }, b: { value: "b" } }
type Test = SomeType<"a" | "b">;

为什么之前的尝试不生效

你之前的写法中,把T声明为泛型参数后,TypeScript会将T视为具体类型而非"类型构造器",因此T<P>这种写法不合法——TypeScript不允许对具体类型传入泛型参数。而上面的方案用函数类型(p: P) => SomeOtherType<P>来模拟类型构造器,通过infer关键字提取每个P对应的返回类型,绕开了这个限制。

关于语法糖的特性支持

你提到的mapof SomeOtherType这类语法糖,目前TypeScript原生并不支持。不过社区一直有关于**高阶类型(Higher-Kinded Types)**的特性提案,该特性允许直接传递泛型类型构造器并在工具类型中使用,但目前还处于讨论阶段,尚未正式纳入TypeScript的核心语法。

替代简化方案

如果觉得上面的模拟写法还是有点繁琐,也可以直接封装更贴合你需求的工具类型:

// 针对你的SomeOtherType直接封装
type MappedToSomeOther<K extends keyof any> = {
  [P in K]: SomeOtherType<P>;
};

// 使用时更简洁
type SomeType<K extends string> = MappedToSomeOther<K>;

这种方式虽然针对性强,但如果有多个类似的SomeOtherType,还是需要重复封装,不过比每次手动写映射类型要简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:23:37