简体   繁体   English

React.FC 中的泛型类型<Props<T> &gt;

[英]GenericType in React.FC<Props<T>>

I'm building a React App based on Hooks, also exploiting TypeScript.我正在构建一个基于 Hooks 的 React 应用程序,也利用了 TypeScript。
I've wrote a component that renders a list, and among its props , it expects props.items , which type is a generic T :我写了一个渲染列表的组件,在它的props ,它需要props.items ,它的类型是一个通用的T

export interface ISelectableListProps<T extends { isDisableInList?: boolean }> {
    /** Specifies the item of the list. */
    items: T[];
    /** Unique REACT key used to re-initialize the component. */
    key?: React.ReactText;
    /** Specifies the template of each item. */
    itemTemplate: (item: T) => JSX.Element;
}

Notice that, in the interface, T also extends { isDisableInList?: boolean } , and that's because each item may have that property, used to disable the item in the list.请注意,在接口中, T还扩展了{ isDisableInList?: boolean } ,这是因为每个项目都可能具有该属性,用于禁用列表中的项目。

Now, for what concern the SelectableList component, I'd like to write this:现在,对于 SelectableList 组件的问题,我想这样写:

const SelectableListComponent: React.FC<ISelectableListProps<T>> = <T extends {}>(props) => { ... }

But TypeScript gives me one error, and one problem:但是 TypeScript 给了我一个错误和一个问题:

  1. ERROR: Type T , in ISelectableListProps<T> is not found; ERROR:类型T ,在ISelectableListProps<T>未找到;
  2. PROBLEM: Type of props is not inferred anymore: it has any .问题:不再推断props类型:它有any . Instead, by removing the <T extends {}> , props type is inferred to be React.PropsWithChildren<ISelectableListProps<any>> ;相反,通过移除<T extends {}>props类型被推断为React.PropsWithChildren<ISelectableListProps<any>>

The only workaround I've found is to define a ItemType , like this:我发现的唯一解决方法是定义一个ItemType ,如下所示:

type ItemType = { isDisableInList?: boolean } & { [key: string]: any };

And then write the component like this:然后像这样编写组件:

const SelectableListComponent: React.FC<ISelectableListProps<ItemType>> = props => { ... }

But doing so, when using the component, props.items is expected to be a ItemType[] , and not a Generic type.但是这样做,在使用组件时, props.items应该是ItemType[] ,而不是 Generic 类型。 In fact, I would like to call the component like this:事实上,我想像这样调用组件:

<SelectableList<MyType> items={...} itemTemplate={...} />

But, as I said, the items is expected to be an ItemType :但是,正如我所说,这些项目应该是一个ItemType 在此处输入图片说明

By the way, no error is given, because ItemType has & { [key: string]: any } , but it seems to me "hacky", almost like using any .顺便说一下,没有给出错误,因为ItemType& { [key: string]: any } ,但在我看来“hacky”,几乎就像使用any

Is there any way I can accomplish what I want?有什么办法可以实现我想要的吗?

There is no way to use React.FC to define a generic component.没有办法使用React.FC来定义通用组件。 You can just use a simple function definition or an arrow function, but letting TS infer the type:您可以只使用简单的函数定义或箭头函数,但让 TS 推断类型:

export interface ISelectableListProps<T extends { isDisableInList?: boolean }> {
    /** Specifies the item of the list. */
    items: T[];
    /** Unique REACT key used to re-initialize the component. */
    key?: React.ReactText;
    /** Specifies the template of each item. */
    itemTemplate: (item: T) => JSX.Element;
}

const SelectableListComponent = <T extends {}>(props: ISelectableListProps<T>) => <></>


Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM