'React component type in TypeScript
What is the correct way to describe the type of a react component in TypeScript? Say we have a function which returns a react component. The function:
const getTabContent: () => ReactElement = () => {
switch (tab) {
case 1:
return <Images images={images} onSelect={onSelect}/>;
default:
return <Search onSelect={onSelect}/>;
}
};
Here I describe the returning type as ReactElement, but I'm wondering whether it's correct or I should describe it as ReactComponentElement or even somehow completely differently? Also those both types are generics and how to fully describe them if one of them is correct?
UPD ReactElement seems to fit here, because, for example, FC (FunctionComponent) returns it
Solution 1:[1]
The correct type for a functional component is React.FunctionComponent
or React.FC
which is a shortcut alias for it
import React, { FC } from 'react';
const getTabContent: FC = () => {
switch (tab) {
case 1:
return <Images images={images} onSelect={onSelect}/>;
default:
return <Search onSelect={onSelect}/>;
}
};
The FC
type simply add the children
property to the props
argument of the functional component so you can access it:
const SomeComponent: FC = ({ children }) => (
<div className="hello">{children}</div>
);
FC
is a generic type so you can "add" props to your component:
interface SomeComponentProps {
foo: string;
}
const SomeComponent: FC<SomeComponentProps> = ({ children, foo }) => (
<div className={`Hello ${foo}`}>{children}</div>
);
Solution 2:[2]
If you want to use FunctionComponent with class Component,
Then use React.ComponentType
Solution 3:[3]
TypeScript comes with powerful type inference. Just use it in most places. Only top-level components required fine-grained interfaces.
For example, here resulting type will be computed as JSX.Element
const getTabContent = ({ tab, onSelect }: { tab: number, onSelect: (ev: React.SyntheticEvent) => void }) => {
switch (tab) {
case 1:
return <Image src="123"/>;
default:
return <Search onSelect={onSelect}/>;
}
};
Solution 4:[4]
Considering this built-in definition in React:
type PropsWithChildren<P> = P & {
children?: React.ReactNode;
}
I am using React.ReactNode
. It is defined as
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Solution 5:[5]
The best option would be ComponentType
. If you are strict about the functional component, You can make use of FC
. In some cases, You might want both class component type and functional component type support. (i.e. Defining a prop type where the prop is expecting a component, either functional or class).
The recommended way is to use ComponentType
in the type definition (i.e. ProopTypes) and FC
when you want to define return type etc.
FYI, Here is the definition of ComponentType
, FC
in typescript
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
type FC<P = {}> = FunctionComponent<P>;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | MJ Studio |
Solution 3 | Alexander Alexandrov |
Solution 4 | igo |
Solution 5 | Kiran Maniya |