TypeScript函数参数中联合类型的类型守卫失效问题
解决TypeScript联合类型函数参数中类型守卫失效的问题
你的问题出在类型守卫的作用范围只针对单个字段item,TypeScript无法自动将字段的类型推断关联到整个联合类型对象上。
方案一:修改类型守卫,针对整个联合类型对象
把类型守卫的参数改成完整的SomeFuncProps对象,直接断言整个对象属于联合类型的目标分支:
// 调整类型守卫,直接校验并断言整个props对象的类型 const isInRangeProps = (props: SomeFuncProps): props is Extract<SomeFuncProps, { item: 'c' | 'd' }> => { return props.item === 'c' || props.item === 'd'; } export type SomeFuncProps = | { item: 'a' | 'b' common: string test2: boolean } | { item: 'c' | 'd' common: string test1: number } const someFunc = (props: SomeFuncProps) => { if (isInRangeProps(props)) { // 类型推断生效,可正常访问test1 console.log(props.test1); } else { // 这里自动推断为第一个分支,可访问test2 console.log(props.test2); } }
方案二:直接在函数内做字段判断(无需额外类型守卫)
如果这个判断逻辑不需要复用,直接在函数里判断item的取值即可——TypeScript会自动识别联合类型的区分字段(discriminant),完成类型缩小:
const someFunc = (props: SomeFuncProps) => { if (props.item === 'c' || props.item === 'd') { console.log(props.test1); // 自动缩小到第二个分支类型 } }
为什么原写法失效?
原类型守卫isInRange只告诉TypeScript当前props.item是'c'|'d',但TypeScript不会反向推导“既然item是这个值,整个props就属于第二个分支”。要让联合类型的类型缩小生效,必须让类型守卫直接关联到整个对象的类型断言,或者直接使用TypeScript原生支持的区分字段自动推断。
内容的提问来源于stack exchange,提问作者Kalap
相关产品推荐
相关产品推荐

