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
React Components Components are independent and reusable bits of code. They serve the same purpose as JavaScript functions, but work in isolation and return HTML via a render() function. Components come in two types, Class components and Function components, in this chapter you will learn about Class components.
React has its own, built-in way of type checking called “prop types”. Together with TypeScript this provides a full, end-to-end type-checking experience: Compiler and run-time.
Using TypeScript, here's how we define the component: // Input. tsx import React from "react"; type Props = { onChange: (str: string) => void; placeholder: string; name: string; value?: string; }; function Input({ onChange, name, placeholder, value = "" }: Props) { return ( <input onChange={event => onChange(event.
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>
);
Edit: React 18 update
Since React 18, FC
doesn't add the children
prop implicitly and offers an explicit way to do so with the PropsWithChildren
generix type
Example:
type SomeComponentProps = { a: string };
const SomeComponent: FC<SomeComponentProps> = ({ a }) => <div>{a}</div>;
// This will fail when using the following expression
<SomeComponent>Hey I'm a child</SomeComponent>
Usage with children:
type ComponentWithChildrenProps = PropsWithChildren<{ a: string }>;
const ComponentWithChildrenProps: FC<ComponentWithChildrenProps> = ({
a,
children
}) => <div>{a} and {children}</div>
This allows to have a children
prop a bit stricter. e.g.
type StrictCompProps = { children: string };
const StrictComp: FC<StrictCompProps> = ({ children }) => <div>{children}</div>;
// This will fail
<StrictComp><span>hey</span></StrictComp>
If you want to use FunctionComponent with class Component,
Then use React.ComponentType
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;
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}/>;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With