reactjs - 如何正确使用 Typescript 中的 React.lazy() 导入带有泛型类型参数的 React 组件?

标签 reactjs typescript typescript-generics

(在 https://github.com/codingismy11to7/lazy-component-typing 重现)

我猜这是 @types/reactLazyExoticComponent 定义的问题...

在带有类型参数的组件上使用 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 | 

最佳答案

TSX 似乎不能很好地处理 props 中的类型参数。

您应该设置一个默认类型参数值,例如 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} /> 

关于reactjs - 如何正确使用 Typescript 中的 React.lazy() 导入带有泛型类型参数的 React 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61667608/

相关文章:

javascript - API不会返回数据

javascript - 突出显示搜索文本 - angular 2

typescript - Typescript 中的类型化通用键值接口(interface)

TypeScript:为什么我不能分配类型为 { a: "a", b: "b"} 的对象的有效字段

typescript - 从类型中删除 undefined

node.js - 如何使用 React-Helmet 优化 SPA 的 SEO?

javascript - 子组件值到父组件显示React Native

typescript - 如何将 Hooks(之前/之后)与 cucumber-js-tsflow 一起使用?

typescript - 类型 'string' 不可分配给类型 'string & number' 。 ts(2322)

reactjs - 使用 react-testing-library 时让 react-datepicker 正确显示