TypeScript中执行"type" in检查后仍报属性不存在错误的疑问
TypeScript类型收窄疑问:为何"in"操作符未正确推断对象类型?
以下代码无法通过TypeScript编译:
const nodeIsUseless = (node: unknown) => node !== null && typeof node === "object" && "type" in node && typeof node.type === "string" && node.type === "JSXText";
报错信息:
Property 'type' does not exist on type 'object'.(2339)
我理解这个错误本身,但疑惑的是:执行"type" in node检查后,TypeScript为什么还是把node推断为object类型,而不是能避免报错的{ type: unknown; [key: string]: unknown }类型?
回答
这是TypeScript对object类型的收窄逻辑导致的:
- 用
typeof node === "object"判断后,TypeScript只会把unknown收窄到宽泛的object顶层类型,它涵盖了所有非原始类型(对象、数组、函数等),不会自动细化成带特定属性的对象结构。 in操作符的类型收窄仅对联合类型生效——比如变量是{a: number} | {b: string}这种联合类型时,"a" in x才能把x收窄到{a: number}。但对于单一的object宽泛类型,in操作符无法触发进一步的类型细化,TypeScript不会主动为它添加具体的属性签名。
要解决这个问题,有两种简单方式:
方式1:使用类型断言
const nodeIsUseless = (node: unknown) => node !== null && typeof node === "object" && "type" in node && typeof (node as { type: unknown }).type === "string" && (node as { type: string }).type === "JSXText";
方式2:自定义类型守卫
interface HasType { type: unknown; } function hasType(node: unknown): node is HasType { return typeof node === "object" && node !== null && "type" in node; } const nodeIsUseless = (node: unknown) => hasType(node) && typeof node.type === "string" && node.type === "JSXText";
这样TypeScript就能正确识别node包含type属性,不会再抛出错误。
内容的提问来源于stack exchange,提问作者Nino Filiu
相关产品推荐
相关产品推荐

