Introduction
I really like explicit return types as you see what will be the result of a function at the first glance. That is why, when I work with TypeScript, I enforce return types by using the "@typescript-eslint/explicit-function-return-type": "error" rule from @typescript-eslint/eslint-plugin in my ESLint configuration. With that ESLint complains when the return type is not explicitly set:
const foo = () => { // Missing return type on function.eslint@typescript-eslint/explicit-function-return-type
return 'bar';
}
Defining general types is straight forward, but when it comes to React there are two potential types you can use for components, JSX.Element and React.FC. In this blog post I am going to explain both types, talks about their pros and cons, and tell you which one I am using.
JSX.Element
JSX.Element defines a representation of a DOM element. In the following example the returned element is a div:
const Example = (): JSX.Element => {
return <div>Hello, world!</div>;
}
Using JSX.Element as the type for React components works in most use-cases, but sometimes components should also be able return null or a simple string. As JSX.Element does represents those types there will be an error:
const Example = (): JSX.Element => {
return null; // Type 'null' is not assignable to type 'Element'.
}
To make the code work the return type has to be extended:
const Example = (): JSX.Element | null => {
return null;
}
React.FC
React.FC on the other hand defines a functional component that returns a JSX element. It is also a generic that can be used to specify component props:
const Example: React.FC<{ name: string }> = (props) => {
return <div>Hello, {props.name}!</div>;
}
Compared to JSX.Element also null and string are represented:
const Example: React.FC = () => {
return null;
}
In former React versions React.FC was avoided as it opened up components with an implicit children prop. Since React 18 this is not the case anymore.
Conclusion
In this blog post I described JSX.ELement and React.FC as types for React components and outlined their pros and cons. Personally I use React.FC over JSX.Element because it does not limit the return type to DOM element representations. Furthermore its generic functionality can be used to define props.