如何为未知嵌套对象正确实现TypeScript类型守卫?
为嵌套结构的未知错误对象实现TypeScript类型守卫
问题场景
第三方库返回的错误对象初始类型为unknown,已知其结构如下:
const myError = { status: 404, data: { foo: "bar" } };
需要自定义类型守卫将其转换为明确的MyError类型,但直接编写的类型守卫出现编译器错误:Property 'data' does not exist on type 'object'.
错误原因
原代码中,即使通过'data' in myError判断了属性存在,TypeScript仍无法自动将unknown类型的myError缩小为包含data属性的对象,直接访问myError.data会触发类型检查报错。此外,原代码仅检查属性是否存在,未验证属性的实际类型(比如status必须是number,foo必须是string),无法确保类型安全。
正确实现
通过逐步缩小类型范围并验证每个属性的类型,实现严谨的类型守卫:
// 定义目标类型 type MyError = { status: number; data: { foo: string; }; }; // 类型守卫函数 const isMyError = (value: unknown): value is MyError => { // 第一步:排除非对象或null的情况 if (typeof value !== 'object' || value === null) { return false; } // 临时断言为包含可选status和data的对象,方便后续检查 const error = value as { status?: unknown; data?: unknown }; // 第二步:验证status是number类型 if (typeof error.status !== 'number') { return false; } // 第三步:验证data是对象且非null if (typeof error.data !== 'object' || error.data === null) { return false; } // 临时断言data为包含可选foo的对象 const data = error.data as { foo?: unknown }; // 第四步:验证foo是string类型 return typeof data.foo === 'string'; };
使用示例
const handleThirdPartyError = (err: unknown) => { if (isMyError(err)) { // 此处err的类型已被推断为MyError,可安全访问嵌套属性 console.log(`状态码: ${err.status}, 错误详情: ${err.data.foo}`); } else { console.log('无法识别的错误类型'); } };
内容的提问来源于stack exchange,提问作者P4nd4b0b3r1n0
相关产品推荐
相关产品推荐

