React Component with TypeScript

 by Robin Wieruch
 - Edit this Post

When using in React, we may want to type their with TypeScript. Overall there are two ways of making a React component type safe with TypeScript, however, let's start by converting the following JavaScript React component to a TypeScript React component as leading example:

const Select = ({ label, value, options, onChange }) => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

The straightforward yet most verbose way of typing this React component would be inlining the types in the functional component's function signature:

const Select = ({
label,
value,
options,
onChange,
}: {
label: string;
value: string;
options: { label: string; value: string }[];
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
}) => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

From there, we would start extracting reusable types from the functional component's function signature into a standalone TypeScript type. It's up to you whether you prefer using a type or interface:

type Option = { label: string; value: string };
type Options = Option[];
const Select = ({
label,
value,
options,
onChange,
}: {
label: string;
value: string;
options: Options;
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
}) => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

Since React props are just a JavaScript object, we can extract a type respectively to the React function component's props too:

type Option = { label: string; value: string };
type Options = Option[];
type SelectProps = {
label: string;
value: string;
options: Options;
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
};
const Select = ({ label, value, options, onChange }: SelectProps) => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

In the beginning I mentioned that there are two ways of make a React component type safe. The last code snippet already showed you one way of doing it. A more popular way would be using TypeScript's type annotation syntax:

type Option = { label: string; value: string };
type Options = Option[];
type SelectProps = {
label: string;
value: string;
options: Options;
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
};
const Select: React.FC<SelectProps> = ({
label,
value,
options,
onChange,
}) => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

After all, the syntax is up to you and your team. It would be important to align on one way of doing it though. Last but not least, you can also define a React component's return type even though it is usually inferred:

const Select: React.FC<SelectProps> = ({
label,
value,
options,
onChange,
}): JSX.Element => {
return (
<label>
{label}
<select value={value} onChange={onChange}>
{options.map((option) => (
<option value={option.value}>{option.label}</option>
))}
</select>
</label>
);
};

That's it. You can make a function component's props type safe in TypeScript by using a type or interface. We have used the former here. In addition, you have two variations of defining types that I have presented here. Last but not least, you can optionally type a function component's return type.

Keep reading about 

When using React's useState Hook in TypeScript, the method usually infers the implicit type for the returned state from the provided argument automatically. In the following example, React's useState…

Type Guards in TypeScript are needed whenever you want to allow only a certain type for a routine in TypeScript. In this TypeScript tutorial, you will learn how to check for user defined types by…

The Road to React

Learn React by building real world applications. No setup configuration. No tooling. Plain React in 200+ pages of learning material. Learn React like 50.000+ readers.

Get it on Amazon.