Объяснение этой сложной ошибки «нельзя назначить типу» в машинописи - PullRequest
1 голос
/ 26 апреля 2020

Я пытаюсь переместить свой проект React в Typescript, но без опыта Typescript. У меня есть Компонент, который определяется следующим образом (обрезается):

interface InputProps {
  handleKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
  placeholder: string;
  style?: React.CSSProperties;
}
const Input: React.ForwardRefRenderFunction<HTMLInputElement, InputProps> = (
      ^^^^^
  { handleKeyDown, placeholder, style }: InputProps,
  ref: React.MutableRefObject<HTMLInputElement | null>
): JSX.Element => {
  return (
    <input
      ref={ref}
      onKeyDown={handleKeyDown}
      type="text"
      placeholder={placeholder}
      style={style}
    />
  );
};
export const ForwardedInput = React.forwardRef(Input);

Теперь я получаю следующую ошибку TypeScript на const Input, и это слишком сложно для меня, чтобы распутать:

TS2322: Type '({ handleKeyDown, placeholder, style }: InputProps, ref: React.MutableRefObject<HTMLInputElement | null>) => JSX.Element' 
is not assignable to type 'ForwardRefRenderFunction<HTMLInputElement, InputProps>'.
  Types of parameters 'ref' and 'ref' are incompatible.
    Type 'MutableRefObject<HTMLInputElement | null> | ((instance: HTMLInputElement | null) => void) | null' is not assignable to type 'MutableRefObject<HTMLInputElement | null>'.
      Type 'null' is not assignable to type 'MutableRefObject<HTMLInputElement | null>'.

Полагаю, мне нужно исправить это, изменив ref: React.MutableRefObject<HTMLInputElement | null> на что-то другое, но я не знаю как, потому что не знаю, что конкретно означает ошибка.

РЕДАКТИРОВАТЬ: В первом ответе предлагалось использовать параметры c, поэтому я адаптировал функцию следующим образом:

const Input = ({ handleKeyDown, placeholder, style }: InputProps, ref: any) => {

Мне пришлось набирать props и ref для предотвращения предупреждений о наборе текста (я использую strict: "true"), и действительно, это удаляет предупреждения в приведенном выше примере кода.

Но ... с использованием любого результата:

ESLint: Unexpected any. Specify a different type.(@typescript-eslint/no-explicit-any)

Согласно это использование any следует избегать, и следует использовать unknown, но, хотя это удаляет предупреждение в заголовке функции, это вызвало большую ошибку в ref={ref} на компоненте ввода, указав ту же несовместимость с ref, что и моя первая ошибка. TypeScript сложнее, чем я думал.

1 Ответ

1 голос
/ 26 апреля 2020

Вы можете использовать общие c параметры для React.forwardRef

export const ForwardedInput = React.forwardRef<HTMLInputElement, InputProps>(
  (props, ref) => {
    const { handleKeyDown, placeholder, style } = props;
    return (
      <input
        ref={ref}
        onKeyDown={handleKeyDown}
        type="text"
        placeholder={placeholder}
        style={style}
      />
    );
  }
);

Ссылка на игровую площадку

Если вам нужно разделить React.forwardRef вызов и его функцию Вы можете использовать React.ForwardRefRenderFunction generi c type.

const ForwardInputRefFunction: React.ForwardRefRenderFunction<HTMLInputElement, InputProps> = (
  props,
  ref
) => {
  const { handleKeyDown, placeholder, style } = props;

  return (
    <input
      ref={ref}
      onKeyDown={handleKeyDown}
      type="text"
      placeholder={placeholder}
      style={style}
    />
  );
};

const ForwardedInput = React.forwardRef(ForwardInputRefFunction);

Playground link

Вы можете исследовать новые типы, читая файлы определений в node_modules. Для этого в изолированной программной среде кода используйте Cmd + Left-click горячую клавишу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...