如何让TypeScript支持接口可选嵌套属性的路径类型检查?
解决可选嵌套属性的路径类型校验问题
问题核心是原Path类型无法处理可选属性的嵌套路径(如address.street),原因是可选属性的类型包含undefined,原逻辑中T[K] extends Record<string, any>会因为undefined不满足条件而终止嵌套。
修改后的类型定义
我们需要先排除undefined,提取可选属性的实际对象类型,再判断是否可以继续嵌套:
type PathImpl<T, K extends keyof T> = K extends string ? // 先获取T[K]的非undefined类型,再判断是否为对象 NonNullable<T[K]> extends Record<string, any> ? `${K}.${Path<NonNullable<T[K]>>}` | K : K : never; export type Path<T> = PathImpl<T, keyof T>; export interface User { name: string; age: number; dimensions: { height: number; weight: number; } address?: { street: string; city: string; state: string; }; } // 所有路径现在都能正常通过校验 const validPath: Path<User> = 'name'; const alsoValidPath: Path<User> = 'address'; const nestedValidPath: Path<User> = 'dimensions.height'; const nowWorksPath: Path<User> = 'address.street'; // 现在可以正常工作了! const alsoNowWorks: Path<User> = 'address.city'; // 同样支持
关键改动说明
- 使用
NonNullable<T[K]>提取可选属性的非undefined部分:对于可选属性address?: { ... },T[K]的类型是{ ... } | undefined,NonNullable会去掉undefined,只保留对象类型。 - 基于处理后的非
undefined类型判断是否可嵌套:只要该类型是对象,就继续递归生成嵌套路径,同时保留当前属性名K作为合法路径。
这样修改后,无论是必填属性的嵌套还是可选属性的嵌套路径,都能被正确识别并通过类型校验。
内容的提问来源于stack exchange,提问作者Daniel Persson
相关产品推荐
相关产品推荐

