如何在React函数组件中正确使用TypeScript判别式联合?
React函数组件中TypeScript判别式联合的正确实现方式
你完全可以用原始的判别式联合定义来实现,不需要重复声明属性并设为null/never。核心是先通过判别式完成类型收窄,再在对应分支里解构属性,而不是一开始就解构所有可能的属性。
步骤示例
首先定义你的判别式联合Props类型:
type MyComponentProps = | { type: 'event'; startDate: Date; endDate: Date } | { type: 'task'; deadline: Date };
错误写法(导致IDE报错)
直接解构所有属性会让TypeScript无法收窄类型,因为它不知道当前type对应的具体分支:
// 错误:startDate可能不存在(当type为'task'时),会抛出TS2339 const MyComponent = ({ type, startDate }: MyComponentProps) => { return <div>{startDate}</div>; };
正确写法1:先判断判别式,再分支内解构
先接收完整的props,通过判别式type做条件判断后,TypeScript会自动收窄当前分支的类型,此时再解构对应属性就不会报错:
const MyComponent = (props: MyComponentProps) => { if (props.type === 'event') { // 此处props已被收窄为event类型,可安全解构startDate/endDate const { startDate, endDate } = props; return ( <div> 活动:{startDate.toLocaleDateString()} 至 {endDate.toLocaleDateString()} </div> ); } else { // 此处props被收窄为task类型,可安全解构deadline const { deadline } = props; return <div>任务:截止日期 {deadline.toLocaleDateString()}</div>; } };
正确写法2:先解构判别式,再分支处理剩余属性
如果需要提前解构通用属性(比如所有分支都有的id、className),可以先解构判别式和通用属性,再在分支里处理剩余属性:
type MyComponentProps = | { type: 'event'; id: string; startDate: Date; endDate: Date } | { type: 'task'; id: string; deadline: Date }; const MyComponent = ({ id, type, ...rest }: MyComponentProps) => { // 通用属性id可直接使用 if (type === 'event') { const { startDate, endDate } = rest; return ( <div id={id}> 活动:{startDate.toLocaleDateString()} 至 {endDate.toLocaleDateString()} </div> ); } else { const { deadline } = rest; return <div id={id}>任务:截止日期 {deadline.toLocaleDateString()}</div>; } };
原理说明
TypeScript的判别式联合类型收窄依赖条件判断语句,只有当你用判别式(比如这里的type字段)明确分支后,TypeScript才能确定当前分支对应的具体类型,此时解构对应属性就会被视为安全操作,不会抛出不存在的属性错误。
内容的提问来源于stack exchange,提问作者foreverAnIntern
相关产品推荐
相关产品推荐

