咨询:使用discriminated union作为React类组件props类型时遇到的问题
咨询:使用discriminated union作为React类组件props类型时遇到的问题
嘿,我之前在开发React类组件的时候也碰到过这个联合类型props收窄的坑,咱们来聊聊怎么解决它~
首先先把你提到的最小示例代码整理出来方便参考:
type TypeAProps = { type: 'a'; valueA: string; }; type TypeBProps = { type: 'b'; valueB: number; }; type UnionProps = TypeAProps | TypeBProps; class MyComponent extends React.Component<UnionProps> { render() { // 这里直接用this.props.type判断的话,TypeScript可能不会正确收窄类型 if (this.props.type === 'a') { // 可能会报错:属性'valueA'在类型'UnionProps'上不存在 return <div>{this.props.valueA}</div>; } else { // 同样可能报错属性'valueB'不存在 return <div>{this.props.valueB}</div>; } } }
这个问题的核心在于:React类组件的this.props是一个动态属性,TypeScript没办法很好地跟踪它的类型变化,哪怕你用判别式type做了判断,它还是会把this.props当成完整的联合类型。
给你几个实用的解决办法:
解构props到局部变量
把props解构出来或者赋值给一个局部变量,TypeScript就能正确识别类型收窄了:render() { const { type, valueA, valueB } = this.props; if (type === 'a') { return <div>{valueA}</div>; } else { return <div>{valueB}</div>; } }直接把this.props赋值给局部变量
如果你不想解构,直接把this.props存到局部变量里也能解决:render() { const props = this.props; if (props.type === 'a') { return <div>{props.valueA}</div>; } else { return <div>{props.valueB}</div>; } }换成函数组件(更推荐)
函数组件对联合类型的类型收窄支持得更自然,写法也更简洁,现在React官方也更推荐函数组件+hooks的写法:const MyComponent: React.FC<UnionProps> = (props) => { if (props.type === 'a') { return <div>{props.valueA}</div>; } return <div>{props.valueB}</div>; };
本质上就是让TypeScript能跟踪到一个固定的、不会动态变化的变量类型,而不是this.props这种可能在类生命周期中被更新的属性。
内容来源于stack exchange
相关产品推荐
相关产品推荐

