TypeScript嵌套JSON对象接口报错:Property 'only'不存在于目标类型
问题原因及解决方案
你的问题出在Menu接口的类型定义和实际使用的结构不匹配,导致TypeScript无法确定menuPermissionForKey的具体类型。
为什么会报错?
你定义的Menu接口使用了索引签名:[key: string]: string[] | Menu,这意味着每个键对应的值可能是字符串数组,也可能是Menu对象。当你访问menuOnlyForRoles.site时,TypeScript只能推断它的类型是string[] | Menu,而string[]类型上并没有only属性,所以直接访问.only就会触发类型错误。
虽然你的实际数据里site是一个带有only属性的对象,但TypeScript只会严格按照你定义的接口做类型检查,不会根据实际赋值的内容自动调整类型。
解决方案1:调整接口定义(推荐)
根据你实际的菜单结构,每个节点都包含only属性,同时可能有子菜单。可以重新定义更精准的接口:
interface MenuNode { // 明确每个节点必须有only属性 only: string[]; // 允许其他键对应子节点(MenuNode)或字符串数组(如果需要的话) [key: string]: string[] | MenuNode; } const menuOnlyForRoles: MenuNode = { site: { only: [], category: { only: ['manager', 'head', 'lead'], }, 'floor-section': { only: ['head', 'lead'], }, }, };
这样调整后,menuOnlyForRoles.site的类型会被推断为MenuNode,直接访问.only就不会有类型错误了。
解决方案2:使用类型守卫(不修改接口时)
如果不想改动原有接口,可以通过类型守卫告诉TypeScript当前值不是字符串数组:
const menuPermissionForKey = menuOnlyForRoles.site || { only: [] }; // 检查是否存在only属性,缩小类型范围 if ('only' in menuPermissionForKey) { const rolesCanAccessMenu = menuPermissionForKey.only || []; // 这里可以安全使用rolesCanAccessMenu }
解决方案3:类型断言(谨慎使用)
如果你能确保运行时menuPermissionForKey一定是带有only属性的对象,可以用类型断言强制指定类型:
const menuPermissionForKey = menuOnlyForRoles.site || { only: [] }; const rolesCanAccessMenu = (menuPermissionForKey as { only: string[] }).only || [];
注意:类型断言相当于你向TypeScript保证这个类型是正确的,如果实际运行时值是字符串数组,会导致运行时错误,所以只在你能确定类型的场景下使用。
内容的提问来源于stack exchange,提问作者tam.dangc
相关产品推荐
相关产品推荐

