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

React TypeScript可复用Input组件size参数冲突报错求解决

修复React TypeScript Input组件size参数冲突问题

问题原因

你定义的自定义size参数(类型为's'|'m')和原生<input>标签的size属性(类型为number | undefined)发生了冲突。当两个类型交叉时,因为没有共同的取值范围,最终size的类型被推断为never,导致TypeScript抛出TS2322错误。

解决方案

方案1:重命名自定义size参数

把自定义的size改成其他名称(比如inputSize),避免和原生属性重名:

import React, { forwardRef } from 'react';
import classNames from 'classnames';

// 修改类型定义,将size改为inputSize
type IInputProps = {
  name?: string;
  inputSize?: 's' | 'm'; // 重命名参数
  status?: '' | 'disabled' | 'invalid';
} & React.ComponentPropsWithRef<'input'>;

const Input = forwardRef<HTMLInputElement, IInputProps>(
  ({ name, inputSize = 'm', status = '', ...rest }: IInputProps, ref) => {
    const inputClassNames = classNames(
      'text-dark w-full ring-2 rounded-full py-1.5 px-3 tracking-wider dark:bg-bright',
      {
        'ring-transparent hover:ring-cyan hover:dark:ring-bright/10 focus-within:outline-none focus-within:border-none focus:ring-cyan':
          status !== 'invalid',
        'ring-transparent border-1 border-amber-600 focus-within:outline-none ':
          status === 'invalid',
        'h-12': inputSize === 'm', // 对应修改引用
        'text-sm h-10': inputSize === 's', // 对应修改引用
        'opacity-50': status === 'disabled',
      },
    );

    return (
      <div className='w-full'>
        <input ref={ref} id={name} name={name} className={inputClassNames} {...rest} />
      </div>
    );
  },
);

Input.displayName = 'Input';

export default Input;

方案2:剔除原生input的size属性

从React.ComponentPropsWithRef<'input'>中移除原生的size属性,保留自定义的size:

import React, { forwardRef } from 'react';
import classNames from 'classnames';

// 使用Omit剔除原生size属性
type IInputProps = {
  name?: string;
  size?: 's' | 'm';
  status?: '' | 'disabled' | 'invalid';
} & Omit<React.ComponentPropsWithRef<'input'>, 'size'>; // 剔除原生size

const Input = forwardRef<HTMLInputElement, IInputProps>(
  ({ name, size = 'm', status = '', ...rest }: IInputProps, ref) => {
    const inputClassNames = classNames(
      'text-dark w-full ring-2 rounded-full py-1.5 px-3 tracking-wider dark:bg-bright',
      {
        'ring-transparent hover:ring-cyan hover:dark:ring-bright/10 focus-within:outline-none focus-within:border-none focus:ring-cyan':
          status !== 'invalid',
        'ring-transparent border-1 border-amber-600 focus-within:outline-none ':
          status === 'invalid',
        'h-12': size === 'm',
        'text-sm h-10': size === 's',
        'opacity-50': status === 'disabled',
      },
    );

    return (
      <div className='w-full'>
        <input ref={ref} id={name} name={name} className={inputClassNames} {...rest} />
      </div>
    );
  },
);

Input.displayName = 'Input';

export default Input;

两种方案都能解决冲突,方案1更直观,避免后续混淆;方案2保留了自定义参数的命名,适合希望保持API语义一致性的场景。

内容的提问来源于stack exchange,提问作者strangeQuirks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:30:01