TypeScript数组中的联合类型未报错问题排查
嘿,我来给你捋捋这个问题哈~ 你遇到的情况其实是TypeScript类型检查机制里一个很常见的点,咱们一步步拆解:
核心原因:没给变量加类型注解,TS自动“脑补”了类型
你现在定义menuData的时候,只是直接写了const menuData = [...],没给它指定MenuElement[]这种明确的类型。这时候TypeScript会自动推断这个变量的类型——它会把你写的所有属性(包括那个多余的undesirableData)都算进这个推断出的类型里。在TS眼里,这个变量本来就应该有这些属性,自然不会报错啦。
只有当你把对象字面量直接赋值给一个有明确类型的变量/参数时,TS才会触发「超额属性检查」,这时候多余的属性才会被揪出来。
给你对比两种写法一看就懂
写法1:无类型注解(不会报错)
type MenuElement = MenuGroup | MenuItem; interface MenuGroup { id: number; name: string; icon?: string; items: MenuItem[]; } interface MenuItem { id: number; name: string; url: string; } // TS会自动推断menuData的类型包含undesirableData const menuData = [ { id: 1, name: 'category', icon: 'star', items: [ { id: 1, name: 'subc...' } ], undesirableData: 'oops' // 完全没提示错误 } ];
写法2:加显式类型注解(立刻报错)
// 明确告诉TS:menuData是MenuElement类型的数组 const menuData: MenuElement[] = [ { id: 1, name: 'category', icon: 'star', items: [ { id: 1, name: 'subc...' } ], undesirableData: 'oops' // 这里TS直接报错:"undesirableData"不在MenuGroup类型里! } ];
顺带提一句:你示例里的小问题
哦对了,你示例里的子菜单{ id: 1, name: 'subc...' }其实缺少MenuItem要求的url属性,同样的,没加类型注解的话TS也不会管,加了类型注解后这个问题也会被检测出来~
怎么解决?
最直接的:给变量加显式类型注解
就像上面写法2那样,给menuData加上: MenuElement[]的类型,TS就会严格校验每个元素的结构,多余属性、缺失属性都会被立刻提示。如果是外部数据(比如API返回):用类型断言+运行时校验
要是你的菜单数据是从后端接口拿的,拿到的是any类型的数据,可以用类型断言告诉TS“这个数据符合我的MenuElement类型”:const menuData = fetchedApiData as MenuElement[];不过要注意,类型断言只是编译时的类型提示,不会在运行时检查数据是否真的符合结构。如果要更安全,建议结合运行时校验工具(比如自己写校验函数),避免前端拿到不符合预期的数据出问题。
内容的提问来源于stack exchange,提问作者user6214985

