TypeScript中如何将含可选参数的嵌套对象叶子值设为undefined并做类型校验
解决方案
直接调整函数的返回类型定义,新增递归工具类型匹配运行时代码逻辑即可,修改后访问深层属性时TypeScript会自动提示上层对象可能为undefined。
核心思路
新增递归工具类型UndefineAllLeaves<T>,实现规则和运行时逻辑完全对齐:
- 所有数组类型、原始类型处理后直接返回
undefined - 无任何属性的空对象处理后直接返回
undefined - 普通对象处理后类型为「所有属性递归处理后的对象」+
undefined联合类型
完整修改后代码
// 递归类型定义:匹配运行时逻辑处理所有属性类型 type UndefineAllLeaves<T> = // 数组类型直接标记为undefined T extends Array<any> ? undefined : // 处理对象类型 T extends object ? // 空对象直接标记为undefined keyof T extends never ? undefined : // 普通对象:属性递归处理 + 本身可能为undefined的联合类型 { [K in keyof T]: UndefineAllLeaves<T[K]> } | undefined : // 原始类型直接标记为undefined undefined export function undefineAllLeafProperties<T extends object>(obj : T): UndefineAllLeaves<T> { const keys : Array<keyof T> = Object.keys(obj) as Array<keyof T>; if(keys.length === 0) return undefined as UndefineAllLeaves<T>; keys.forEach(key => { if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) { obj[key] = undefineAllLeafProperties(<any>obj[key]) as T[keyof T]; } else { obj[key] = undefined!; } }); return obj as UndefineAllLeaves<T>; }
效果验证
使用示例测试,类型校验完全符合预期:
class Person { name: string = 'name'; address: {street?: string, pincode?: string} = {}; } const undefperson = undefineAllLeafProperties(new Person); // 执行下行代码时TypeScript会抛出错误:对象可能为“未定义” undefperson.address.street = ''
内容的提问来源于stack exchange,提问作者Ayyappa
相关产品推荐
相关产品推荐

