TypeScript中合并条件映射类型的实现方法
TypeScript 筛选对象键生成完整类型问题
基础定义
先看这个基础接口:
interface A { a: string b: number c: number }
之前的联合类型生成方式
如果用自身键索引映射类型,比如这段代码:
type B = { [K in keyof A]: { [K_ in K]: A[K_] } }[keyof A]
会生成由单个键值对组成的联合类型:
type B = { a: string; } | { b: number; } | { c: number; }
进一步做条件筛选,只保留值类型为number的键,代码如下:
type C = { [K in keyof A]: A[K] extends number ? { [K_ in K]: A[K_] } : never }[keyof A]
但结果还是联合类型:
type C = { b: number; } | { c: number; }
需求
现在要调整写法,直接生成包含所有符合条件键值对的完整对象类型,也就是得到:
type C = { b: number; c: number; }
实现方案
不用绕联合类型,直接利用TypeScript的键重映射特性,在映射时直接剔除不符合条件的键:
通用工具类型写法
// 定义通用工具类型:筛选出T中值类型为U的键值对 type FilteredObject<T, U> = { [K in keyof T as T[K] extends U ? K : never]: T[K] } // 针对接口A筛选值为number的键 type C = FilteredObject<A, number>
内联写法
如果不需要复用,也可以直接写:
type C = { [K in keyof A as A[K] extends number ? K : never]: A[K] }
两种写法最终生成的C都是你想要的完整对象类型。原理是通过as关键字控制键的保留:当键K对应的A[K]是number类型时,保留这个键;否则返回never,TypeScript会自动从最终类型中移除值为never的键。
内容的提问来源于stack exchange,提问作者asnaeb
相关产品推荐
相关产品推荐

