如何创建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
相关产品推荐
相关产品推荐

