TypeScript泛型报错:类型'User | PrivateUser'不存在'token'属性
解决TypeScript泛型函数中访问联合类型属性的TS2339错误
问题原因:你的泛型函数fn的类型参数T约束为User | PrivateUser,TypeScript无法自动推断传入的obj是否包含token属性——当T是User类型时,该属性不存在,因此直接访问obj.token会触发类型错误。
以下是几种可行的解决方法:
方法1:使用in操作符做类型缩小(推荐)
TypeScript支持通过in操作符判断对象是否包含某个属性,同时自动缩小变量的类型范围。先重构接口让PrivateUser继承User以减少重复代码,再用in判断:
interface User { id: string; info: string; } // 继承User,复用公共属性 interface PrivateUser extends User { token: string; } const obj1: User = { id: '123', info: 'test-1' }; const obj2: PrivateUser = { id: '123', info: 'test-1', token: '' }; const fn = <T extends User | PrivateUser>(obj: T): T => { // TypeScript会自动将obj类型缩小为PrivateUser if ('token' in obj) { obj.token = 'test'; } return obj; };
方法2:自定义类型守卫函数
如果需要更严谨的类型判断逻辑,可以编写自定义类型守卫:
interface User { id: string; info: string; } interface PrivateUser extends User { token: string; } // 自定义类型守卫,明确判断对象是否为PrivateUser类型 function isPrivateUser(obj: User | PrivateUser): obj is PrivateUser { return typeof (obj as PrivateUser).token === 'string'; } const obj1: User = { id: '123', info: 'test-1' }; const obj2: PrivateUser = { id: '123', info: 'test-1', token: '' }; const fn = <T extends User | PrivateUser>(obj: T): T => { if (isPrivateUser(obj)) { obj.token = 'test'; } return obj; };
方法3:类型断言(不推荐)
类型断言可以跳过TypeScript的类型检查,但这种方式不安全——若传入不符合预期的对象,可能引发运行时问题:
const fn = <T extends User | PrivateUser>(obj: T): T => { if ((obj as PrivateUser).token) { (obj as PrivateUser).token = 'test'; } return obj; };
内容的提问来源于stack exchange,提问作者Mykhailo Toporkov
相关产品推荐
相关产品推荐

