React TypeScript组件如何条件调用可选函数props不触发编译错误
解决方案
你遇到的报错本质是当前的AnimalProps类型没有建立animalName取值和对应函数属性的关联,TypeScript无法通过animalName的判断自动收窄可选属性的存在性,以下是几种不同场景的实现方案:
方案1:重构为可辨识联合类型(最推荐,类型安全)
直接修改属性定义,将不同动物的属性拆分后做联合类型,TypeScript会自动根据animalName的取值收窄类型,无需任何额外断言:
// 定义可辨识联合类型 type AnimalProps = | { animalName: 'dog' bark: () => void } | { animalName: 'fish' swim: () => void } const Animal = (props: AnimalProps) => { if (props.animalName === 'dog') { // 此处TypeScript自动识别props必然存在bark属性,不会报错 props.bark() } if (props.animalName === 'fish') { props.swim() } /* 渲染逻辑 */ }
如果你需要保留公共属性,可以单独抽离基础类型再扩展:
interface AnimalBase { age?: number gender?: 'male' | 'female' } type AnimalProps = AnimalBase & ( | { animalName: 'dog'; bark: () => void } | { animalName: 'fish'; swim: () => void } )
方案2:使用非空断言(适合100%确定属性必然存在的场景)
如果你不想修改原有类型定义,且可以保证对应animalName下对应的函数必然传入,可以在调用时添加非空断言操作符!,告诉TypeScript该值不可能为undefined:
const Animal = ({ animalName, bark, swim }: AnimalProps) => { if (animalName === 'dog') { bark!() // ! 表示你确定bark一定存在 } if (animalName === 'fish') { swim!() } /* 渲染逻辑 */ }
注意:该方案没有运行时保护,如果实际未传入对应函数,运行时会抛出异常。
方案3:添加运行时校验(兼顾类型和运行时安全)
调用前先判断函数是否存在,TypeScript会自动收窄类型,就算类型定义错误也不会导致运行时报错:
const Animal = ({ animalName, bark, swim }: AnimalProps) => { if (animalName === 'dog' && typeof bark === 'function') { bark() } if (animalName === 'fish' && typeof swim === 'function') { swim() } /* 渲染逻辑 */ }
方案4:设置默认空函数
解构属性时给可选函数属性设置默认值为空函数,就算未传入调用也不会有任何问题:
const Animal = ({ animalName, bark = () => {}, swim = () => {} }: AnimalProps) => { if (animalName === 'dog') { bark() } if (animalName === 'fish') { swim() } /* 渲染逻辑 */ }
内容的提问来源于stack exchange,提问作者Noobcoder
相关产品推荐
相关产品推荐

