Как правильно использовать React.lazy () в Typescript для импорта компонента реакции с параметром типа generi c? - PullRequest
1 голос
/ 07 мая 2020

(воспроизведение на https://github.com/codingismy11to7/lazy-component-typing)

Я предполагаю, что это проблема с @types/react и определением LazyExoticComponent ...

Когда используя React.lazy() в компоненте с параметром типа, Typescript больше не может компилировать проект.

Учитывая компонент:

import React from "react";

export interface Props<T> {
  value: T;
  valueCallback: (t: T) => void;
}

export default function TypedComponent<T>(props: Props<T>) {
  return (
    <>
      <div>{`${props.value}`}</div>
      <button onClick={() => props.valueCallback(props.value)}>click</button>
    </>
  )
}

Это компилирует:

import React, {useState} from "react";
import TypedComponent from "./TypedComponent";

export default function StrictComponent() {
  const [state, setState] = useState("blah");

  return (
    <TypedComponent value={state} valueCallback={setState}/>
  );
}

пока этого не происходит:

import React, {lazy, useState} from "react";
const TypedComponent = lazy(() => import("./TypedComponent"));

export default function LazyComponent() {
  const [state, setState] = useState("blah");

  return (
    <TypedComponent value={state} valueCallback={setState}/>
  );
}
TypeScript error in D:/dev/lazy-component-typing/src/LazyComponent.tsx(9,35):
Type 'Dispatch<SetStateAction<string>>' is not assignable to type '(t: unknown) => void'.
  Types of parameters 'value' and 't' are incompatible.
    Type 'unknown' is not assignable to type 'SetStateAction<string>'.
      Type 'unknown' is not assignable to type '(prevState: string) => string'.  TS2322

     7 | 
     8 |   return (
  >  9 |     <TypedComponent value={state} valueCallback={setState}/>
       |                                   ^
    10 |   );
    11 | }
    12 | 

1 Ответ

0 голосов
/ 08 мая 2020

TSX, похоже, не очень хорошо работает с аргументами типа в реквизитах.

Вы должны установить значение параметра типа по умолчанию, например any, но это будет предполагать, что ваши типы всегда any при использовании компонента, который может быть не совсем тем, что вам нужно:

export interface Props<T = any> {
  value: T;
  valueCallback: (t: T) => void;
}

// ...

// `valueCallback` will pass an explicit `any`
<TypedComponent value={value} valueCallback={setState} />

Вы можете попробовать скопировать его с допустимым расширенным типом, а затем использовать его, например:

import { Props as TCProps } from './TypedComponent'
const StronglyTypedComponent: React.Component<TCProps<string>> = TypedComponent

// ...

// correctly typed, but more verbal
<StronglyTypedComponent value={value} valueCallback={setState} /> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...