如何在TypeScript中对允许部分子树的嵌套记录做正确类型检查
TypeScript check函数类型定义实现方案
以下是满足需求的完整实现:
interface Data { namespace1: { keyA: string, keyB: string }, namespace2: { keyC: string, keyD: string } } // 递归构造深度可选类型,支持传入schema任意层级的子树 type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T; // 递归校验结构合法性,异常场景返回友好错误提示 type ValidateStruct<T, Schema> = T extends object ? { [K in keyof T]: K extends keyof Schema ? ValidateStruct<T[K], Schema[K]> : `错误:不存在的字段 "${K & string}",请检查字段名` } : T extends Schema ? T : `错误:字段值类型不匹配,预期为${Schema}`; function check<T extends DeepPartial<Data>>( partialData: T extends ValidateStruct<T, Data> ? T : ValidateStruct<T, Data> ): T { return partialData; }
实现说明
DeepPartial递归将Data所有层级的属性标记为可选,满足传入任意子树(包括空对象)的需求。ValidateStruct递归遍历传入的参数结构,遇到不在schema中的字段直接返回带字段名的错误提示,值类型不匹配也返回对应提示,避免晦涩的never类型报错。- 函数泛型先限制传入参数必须是
DeepPartial<Data>的子类型,校验不通过时直接将参数类型替换为带错误提示的结构,编译器报错时会直接展示自定义的错误文本,可读性更高。
所有示例测试效果和需求完全匹配:
- 三个合法输入示例正常通过编译,返回值保留完整的输入类型信息
- 示例4传入
namespace1.keyC时,提示错误:不存在的字段 "keyC",请检查字段名 - 示例5传入
xyz字段时,提示错误:不存在的字段 "xyz",请检查字段名
内容的提问来源于stack exchange,提问作者Natasha
相关产品推荐
相关产品推荐

