TypeScript联合类型中仅某类型含有的属性访问问题
解决TypeScript联合类型数组访问专属属性的类型错误问题
你的问题核心是:数组里同时存在One和Two类的实例(联合类型One | Two),TypeScript无法确定遍历到的每一项具体是哪个类型,所以直接访问仅One拥有的drawer属性会触发类型错误。下面是几种安全且符合TypeScript类型规范的解决方式:
方法1:使用instanceof类型守卫(最适合类实例场景)
因为One和Two都是类,TypeScript可以通过instanceof直接判断实例所属的类,自动收窄类型:
arrayWithBothOneAndTwo.forEach((item) => { // 判断item是否是One类的实例 if (item instanceof One) { console.log(item.drawer); // 这里TypeScript明确知道item是One类型,可安全访问drawer } })
方法2:用in操作符直接做类型收窄
如果不想用instanceof,也可以通过检查属性是否存在来收窄类型:
arrayWithBothOneAndTwo.forEach((item) => { // 检查item是否包含drawer属性 if ('drawer' in item) { console.log(item.drawer); // TypeScript会自动将item类型收窄为One } })
方法3:自定义类型谓词函数(适合复杂判断场景)
如果需要复用类型判断逻辑,可以写一个自定义的类型守卫函数:
// 定义类型谓词,告诉TypeScript如果函数返回true,item就是One类型 function isOne(item: One | Two): item is One { return 'drawer' in item; } arrayWithBothOneAndTwo.forEach((item) => { if (isOne(item)) { console.log(item.drawer); } })
为什么你之前的方法无效?
你尝试强制声明数组为One[]或给forEach参数指定One类型,本质是跳过了TypeScript的类型检查,但数组里实际包含Two的实例,这样写会埋下运行时错误的隐患。TypeScript的报错是在帮你提前规避这类问题,正确的做法是通过类型收窄让TypeScript明确当前项的类型,而不是强行断言。
内容的提问来源于stack exchange,提问作者CaptainCarl
相关产品推荐
相关产品推荐

