TypeScript:无法访问函数参数对象中属性的问题
原因解释
1. TypeScript联合类型的类型收窄限制
TypeScript的类型检查器无法通过identifier === 'dog'这个条件,自动把data的类型从CatProps | DogProps收窄到DogProps。因为identifier和data是两个独立的函数参数,TypeScript没有能力推断它们之间的关联逻辑——它不知道当identifier是'dog'时,data一定对应DogProps类型,反之亦然。
所以在if(identifier === 'dog')分支里解构height等属性时,TypeScript仍然认为data可能是CatProps(而CatProps没有height),因此抛出错误;同理,else分支里解构feedingTime时,TypeScript认为data可能是DogProps(而DogProps没有feedingTime),也会报错。
2. 为什么any类型能解决问题
any是TypeScript中最宽松的类型,它会完全绕过所有类型检查规则。当你把data的类型设为any时,TypeScript会放弃对该变量的属性校验,不管你解构什么属性,它都不会报错。但这种做法会丢失TypeScript的类型安全优势,容易埋下运行时bug,不建议作为常规解决方案。
可选的正确解决方式
要让TypeScript正确识别参数间的类型关联,可以用以下两种方式:
方式1:手动类型断言
在分支里明确告诉TypeScriptdata的具体类型:
const functionTwo = (data: AnimalStateEntries['allStatesSingular'], identifier: keyof AnimalState) => { if(identifier === 'dog') { const {height, breed, allergies} = data as DogProps } else { const {feedingTime, color, old} = data as CatProps } }
方式2:泛型绑定类型关联
通过泛型让identifier和data的类型强绑定,让TypeScript自动推断:
type AnimalType = keyof AnimalState; type AnimalProps<T extends AnimalType> = T extends 'dog' ? DogProps : CatProps; const functionTwo = <T extends AnimalType>(data: AnimalProps<T>, identifier: T) => { if(identifier === 'dog') { const {height, breed, allergies} = data // 自动推断为DogProps } else { const {feedingTime, color, old} = data // 自动推断为CatProps } }
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

