基于Props条件渲染JSX时的TypeScript联合类型错误
解决方案:TypeScript联合类型的类型收窄问题
首先要明确:你遇到的核心问题是TypeScript无法通过普通的条件判断自动收窄联合类型,解决的关键是给联合类型的每个成员添加字面量类型的区分属性,再通过该属性完成类型守卫。
步骤1:修正类型定义
确保CoachType和ReviewType拥有字面量类型的type属性(而非宽泛的string类型),这是TypeScript识别不同类型分支的基础:
// 教练类型:type为字面量'coach' type CoachType = { type: 'coach'; firstName: string; lastName: string; // 其他教练专属属性 }; // 评论类型:type为字面量'review' type ReviewType = { type: 'review'; reviewText: string; reviewer: string; // 其他评论专属属性 }; // 联合类型 type CardType = CoachType | ReviewType;
步骤2:在React组件中完成类型收窄
通过if-else或switch-case判断type属性,TypeScript会自动将联合类型收窄为对应分支的具体类型,此时就能安全访问专属属性:
方式一:if-else判断
import React from 'react'; const CoachCard = (props: { data: CardType }) => { const { data } = props; if (data.type === 'coach') { // 这里TypeScript明确知道data是CoachType,可安全访问firstName等属性 return ( <div className="card"> <h2>{data.firstName} {data.lastName}</h2> {/* 其他教练卡片内容 */} </div> ); } else { // 这里TypeScript明确知道data是ReviewType,可安全访问reviewText等属性 return ( <div className="card"> <h3>来自{data.reviewer}的评价</h3> <p>{data.reviewText}</p> {/* 其他评论卡片内容 */} </div> ); } }; export default CoachCard;
方式二:switch-case判断
import React from 'react'; const CoachCard = (props: { data: CardType }) => { const { data } = props; switch (data.type) { case 'coach': return ( <div className="card"> <h2>{data.firstName} {data.lastName}</h2> </div> ); case 'review': return ( <div className="card"> <h3>来自{data.reviewer}的评价</h3> <p>{data.reviewText}</p> </div> ); default: // 兜底处理未知类型,避免编译报错 throw new Error(`未知卡片类型:${(data as never).type}`); } }; export default CoachCard;
为什么之前的switch-case无效?
大概率是因为你最初定义的type属性是宽泛的string类型(而非字面量类型),比如:
// 错误示例:type为string,TypeScript无法区分分支 type CoachType = { type: string; // 这里应该写成'type: 'coach'' firstName: string; };
这种情况下,data.type === 'coach'的判断无法让TypeScript确定当前类型是CoachType,自然会报错属性不存在。
内容的提问来源于stack exchange,提问作者Ryan Black
相关产品推荐
相关产品推荐

