如何创建TypeScript递归类型表示嵌套对象属性路径联合
构建TypeScript嵌套属性路径联合类型的问题与解决方案
问题描述
我需要编写一个TypeScript类型定义,用来生成某类型中所有可能的嵌套属性路径的联合类型。尝试了以下代码,但运行报错:
interface Address { city: string; } interface Client { name: string; address: Address } type PropertyNames<T> = T extends { [K in keyof T]: any } ? K | `${K & string}.${PropertyNames<T[K]>}` : never;
预期这个PropertyNames类型能生成包含所有嵌套属性路径的联合类型,例如:
const key1: PropertyNames<Client> = "name"; const key2: PropertyNames<Client> = "address.city";
但TypeScript抛出错误:Cannot find name 'K'
解决方案
参考@jcalz的方案并做了适配Date和Array类型的修改,最终可用代码如下:
type PropertyNames<T> = T extends object ? { [K in string & keyof T]: T[K] extends Date | undefined ? K // 遇到Date类型停止递归 : T[K] extends Array<infer A> | undefined ? K | `${K & string}.${PropertyNames<A>}` // 数组类型递归处理其元素的属性路径 : K | `${K & string}.${PropertyNames<T[K]>}`; }[string & keyof T] : never;
关键逻辑说明
- 先判断目标类型
T是否为对象,非对象类型直接返回never - 遍历类型的所有字符串键
K:- 若属性是
Date或undefined,仅返回当前键,终止递归 - 若属性是数组类型,同时保留当前键和数组元素的嵌套属性路径
- 其他对象类型则同时保留当前键和其嵌套属性的路径
- 若属性是
内容的提问来源于stack exchange,提问作者Olivier Lecrivain
相关产品推荐
相关产品推荐

