TypeScript中能否将参数param的类型从T0 | T1重新分配为T0类型?
TypeScript联合类型窄化:通过
hasOwnProperty判断后如何将类型重新分配为T0? 先看你给出的代码示例:
type T0 = { a: string; b: string } type T1 = Omit<T0, 'b'> function func({ param }: { param: T0 | T1 }) { if (param.hasOwnProperty('b')) { /* reassign type */ } return param.b // 这里会触发TS类型错误,因为T1没有b属性 }
当然有可行的方法!不过要说明:原生的hasOwnProperty()调用并不会让TypeScript自动把param的类型从T0 | T1窄化为T0——TS对这个方法的类型推导没有做特殊优化。下面给你两个实用的解决方案:
方案1:用in操作符实现自动类型窄化
这是最直接的方法,TS原生支持用in操作符根据属性存在性来窄化联合类型,完全不需要额外代码:
type T0 = { a: string; b: string } type T1 = Omit<T0, 'b'> function func({ param }: { param: T0 | T1 }) { if ('b' in param) { // 到这里TS已经自动把param推断为T0类型了 console.log(param.b) // 类型安全,不会报错 return param.b } // 处理T1的情况,避免返回值类型错误 return 'b属性不存在' }
方案2:自定义类型守卫函数(如果一定要用hasOwnProperty)
如果你坚持要使用hasOwnProperty来判断,可以写一个自定义类型守卫函数,手动告诉TS如何根据判断结果推导类型:
type T0 = { a: string; b: string } type T1 = Omit<T0, 'b'> // 自定义类型守卫:返回true时,obj会被TS推断为T0类型 function isT0(obj: T0 | T1): obj is T0 { return obj.hasOwnProperty('b') } function func({ param }: { param: T0 | T1 }) { if (isT0(param)) { // 这里param已经被窄化为T0类型 return param.b } // 必须处理T1的分支,保证类型完整性 return '默认值' }
补充:为什么hasOwnProperty默认不行?
因为hasOwnProperty的返回值只是普通的boolean类型,TS无法从这个布尔值直接关联到对象的属性存在性与类型的对应关系。而in是TS专门做了类型优化的语法,它能直接建立“属性存在”和“类型匹配”的关联。
内容的提问来源于stack exchange,提问作者dprks
相关产品推荐
相关产品推荐

