TypeScript实现无需指定路径的深层按Key取值泛型
解决TypeScript DeepKeys泛型数组遍历问题
问题场景
现有如下TypeScript类型:
type Form = { collateral: { id: "collateralField", default: "", deps: ["collateralToken", "borrowInput", "asd"], severities: { first: 'first', second: 'second' } }, borrow: { id: "borrowField", name: "Borrow" }, }
需求是创建泛型DeepKeys<T, Q>,接收类型T和查询字符串Q,返回所有匹配键Q的值的联合类型。例如:
type IDs = DeepKeys<Form, "id"> // 期望结果:"collateralField" | "borrowField"
当前实现会遍历数组对象并引入不必要的内容:
type DeepKeys<T, Q> = T extends object ? { [K in keyof T]: (K extends Q ? T[K] : never) | DeepKeys<T[K], Q> }[keyof T] : never;
修正后的实现
要解决数组遍历的问题,只需在处理对象前先排除数组类型,因为我们不需要递归遍历数组元素。修正后的代码如下:
type DeepKeys<T, Q extends PropertyKey> = // 数组类型直接返回never,不递归遍历元素 T extends any[] ? never : T extends object ? { [K in keyof T]: // 当前键匹配Q时取对应值,否则递归处理子类型 (K extends Q ? T[K] : never) | DeepKeys<T[K], Q> }[keyof T] : never;
验证结果
测试目标场景:
type IDs = DeepKeys<Form, "id"> // 结果:"collateralField" | "borrowField" 符合期望
测试嵌套字段场景:
type SeverityValues = DeepKeys<Form, "first"> // 结果:"first"
测试数组字段场景:
type DepsField = DeepKeys<Form, "deps"> // 结果:["collateralToken", "borrowInput", "asd"] 正确返回数组类型,不会遍历数组元素
内容的提问来源于stack exchange,提问作者Giulio
相关产品推荐
相关产品推荐

