Typescript中Student继承User时如何声明两者联合类型并访问独有属性
错误原因
你遇到的报错不是TS默认匹配父接口导致的,是TypeScript针对联合类型的固有规则:对于T1 | T2类型的变量,默认只允许访问T1和T2两种类型共有的属性,以此保证类型安全。在你的场景中currentTeam仅Student类型拥有,User类型不存在该属性,TS无法确定运行时userData的具体类型,因此抛出2339错误。
可行解决方案
你可以根据业务场景选择以下任意一种方案实现需求:
- 方案1:类型守卫缩小类型(最推荐,无运行时风险)
先定义自定义类型守卫判断变量是否为Student类型,再访问独有属性:// 自定义类型守卫,返回值为类型谓词,告诉TS判断为true时变量是Student类型 function isStudent(user: Student | User): user is Student { // 可以用in运算符判断独有属性是否存在,也可以用其他可区分的标识,比如用户类型字段 return user !== null && 'currentTeam' in user; } // 业务代码中使用 if (isStudent(userData)) { // 此处TS会自动将userData识别为Student类型,可正常访问currentTeam console.log(userData.currentTeam); } - 方案2:类型断言(适合你100%确定当前场景下userData是Student类型的场景)
直接告诉TS当前变量的类型为Student,跳过类型校验:// 两种断言写法均可 const team = (userData as Student)?.currentTeam; // 或者 const team = (<Student>userData)?.currentTeam;注意:类型断言属于强制覆盖TS的类型判断,如果运行时实际拿到的是User类型,访问
currentTeam会得到undefined,存在业务风险,谨慎使用。 - 方案3:改造为可辨识联合(适合多类型统一管理的场景)
给User和Student接口都添加同一个可辨识的标识字段,后续TS可以自动根据标识缩小类型:
业务使用时直接判断标识字段即可:interface User { // 原有属性不变,新增公共标识字段 userType: 'common' | 'student'; } interface Student extends User { userType: 'student'; // 原有Student独有属性不变 currentTeam: string; }if (userData?.userType === 'student') { console.log(userData.currentTeam); }
内容的提问来源于stack exchange,提问作者Rafael Zasas
相关产品推荐
相关产品推荐

