You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据布尔值isTextArea正确定义React组件类型?

如何为Input组件正确区分input和textarea的Props类型?

我尝试通过布尔值isTextArea为Input组件区分input和textarea的Props类型,但出现类型错误,请问该如何正确定义对应类型?

我的代码如下:

type InputProps =
   | ({
        isTextArea: false;
        label: string;
     } & React.ComponentPropsWithoutRef<'input'>)
   | ({
        isTextArea: true;
        label: string;
     } & React.ComponentPropsWithoutRef<'textarea'>);


const Input: React.FC<InputProps> = ({ isTextArea, label, ...props }) => {
   return (
      <div className='w-full'>
         <label htmlFor=''></label>
         {isTextArea ? <textarea {...props} /> : <input {...props} />}
      </div>
   );
};

export default Input;

问题原因

提前解构props后,TypeScript无法再通过isTextArea这个判别式缩小props的类型——解构后的props会被推断为input和textarea所有属性的交集,而两者存在不兼容属性(比如rows为textarea独有、type为input独有),因此会触发类型不匹配错误。

修复方案

方案一:保留完整props对象进行类型缩小

不要提前解构props,直接在条件分支中使用完整的props对象,让TypeScript通过isTextArea自动识别对应类型:

type InputProps =
   | ({
        isTextArea: false;
        label: string;
     } & React.ComponentPropsWithoutRef<'input'>)
   | ({
        isTextArea: true;
        label: string;
     } & React.ComponentPropsWithoutRef<'textarea'>);


const Input: React.FC<InputProps> = (props) => {
   const { isTextArea, label } = props;
   return (
      <div className='w-full'>
         <label htmlFor=''></label>
         {isTextArea ? <textarea {...props} /> : <input {...props} />}
      </div>
   );
};

export default Input;

方案二:解构后用类型断言明确属性类型

如果需要避免把isTextArea和label传递给原生元素,可以解构后对剩余属性做类型断言:

type InputProps =
   | ({
        isTextArea: false;
        label: string;
     } & React.ComponentPropsWithoutRef<'input'>)
   | ({
        isTextArea: true;
        label: string;
     } & React.ComponentPropsWithoutRef<'textarea'>);


const Input: React.FC<InputProps> = (props) => {
   const { isTextArea, label, ...rest } = props;
   return (
      <div className='w-full'>
         <label htmlFor=''></label>
         {isTextArea ? (
            <textarea {...(rest as React.ComponentPropsWithoutRef<'textarea'>)} />
         ) : (
            <input {...(rest as React.ComponentPropsWithoutRef<'input'>)} />
         )}
      </div>
   );
};

export default Input;

方案一更简洁安全,TypeScript能完整识别分支中的props类型;方案二适合需要单独处理多余属性的场景。

内容的提问来源于stack exchange,提问作者Mateusz Dariusz Szymczyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:32:43