如何在Typescript中访问React组件内有条件声明的props属性
问题根因
你定义的LoaderProps是TypeScript可辨识联合类型,local是类型辨识键。你在解构props时把local单独拆成了独立变量,剩余的...props不再包含local字段,TypeScript无法建立「local === 'relative'」和「剩余props存在contentAlign」之间的类型关联,因此访问props.contentAlign会抛出类型错误。另外你原代码中的className属性存在语法错误,多写了一层大括号且多余了闭合符号,同时用&&拼接会在条件不成立时返回布尔值作为类名,属于无效写法。
可行解决方案
方案1:先做类型收窄再解构(最推荐,无额外代码,TS可自动推导)
不解构完整props对象,先通过辨识键收窄整体类型后再访问属性:
export type LoaderProps = { className?: string; background?: string; size?: number; } & ( | { local?: Nullable<boolean>; } | { local: 'relative'; contentAlign: LoaderContentAlign; } ); const Loader: React.FC<LoaderProps> = (props: LoaderProps) => { // 先提取公共属性 const { className, background = 'blue', size = 30, local = false } = props; return ( <div className={props.local === 'relative' ? `loader_content-${props.contentAlign}` : ''} > Content </div> ); };
此时TS可以通过props.local的判断自动收窄类型,直接访问props.contentAlign不会报错。
方案2:类型断言(适合逻辑确定的场景,写法最简单)
如果你确定local === 'relative'时contentAlign一定存在,可以用类型断言跳过TS检查:
const Loader: React.FC<LoaderProps> = ({ className, background = 'blue', local = false, size = 30, ...props }: LoaderProps) => { return ( <div className={local === 'relative' ? `loader_content-${(props as { contentAlign: LoaderContentAlign }).contentAlign}` : ''} > Content </div> ); };
方案3:自定义类型守卫(适合多场景复用的情况)
如果多处需要判断该类型,可以定义独立的类型守卫做显式收窄:
// 定义类型守卫 const isRelativeLoader = (local: LoaderProps['local'], props: unknown): props is { contentAlign: LoaderContentAlign } => { return local === 'relative'; }; const Loader: React.FC<LoaderProps> = ({ className, background = 'blue', local = false, size = 30, ...props }: LoaderProps) => { return ( <div className={isRelativeLoader(local, props) ? `loader_content-${props.contentAlign}` : ''} > Content </div> ); };
内容的提问来源于stack exchange,提问作者KAVA
相关产品推荐
相关产品推荐

