Different ways to strongly-type function component props with TypeScript
One of the most beneficial parts of using TypeScript with React is the ability to have strongly-typed component props. This allows developers using the component to quickly understand what they can pass and helps them avoid making a mistake.
In this post, we will go through several different approaches to strongly-typing a function component props. We are going to strongly-type the props for the following component:
const TextField = ({  label,  text,  onTextChange}) => (  <div>    <label>{label}</label>    <input      type="text"      value={text}      onChange={e =>        onTextChange(e.currentTarget.value)      }    />  </div>);Inline type annotation
Perhaps the simplest approach is to use an inline type annotation on the props function parameter:
const TextField = ({  label,  text,  onTextChange}: {  label: string;  text: string;  onTextChange: (text: string) => void;}) => ...This is a nice approach when there are only a couple of props in our component, and the props don’t need to be reused.
This can also be used if the component is a regular function rather than an arrow function:
function TextField({  label,  text,  onTextChange}: {  label: string,  text: string,  onTextChange: (text: string) => void}) {  ...}Type alias
We could extract the props into a type alias:
type Props = {  label: string;  text: string;  onTextChange: (text: string) => void;};const TextField = ({  label,  text,  onTextChange}: Props) => ...This is great when there are at least a few props, or we want to reuse the props type across multiple components.
Again, this approach can be used for regular function components:
function TextField({  label,  text,  onTextChange}: Props) ...Interface
We can use an interface instead of a type alias:
interface Props {  label: string;  text: string;  onTextChange: (text: string) => void;}Interfaces have very similar capabilities to type aliases these days, so it’s generally a personal preference for which to use.
FC type
There is a standard React type, FC, that we can use on arrow function components. “FC” stands for Function Component, and it aliases a type called FunctionComponent.
const TextField: React.FC<Props> = ({  label,  text,  onTextChange}) => ...The FC type is used on the variable assigned to the arrow function. It is a generic type that we pass the components props type into.
There are some arguable minor benefits to using the FC type:
- FCprovides some type safety on- defaultProps, which can be used to provide default values for the props. However,- defaultPropsmay be removed from React in a future release.
- FCincludes the- childrenprop type, so you don’t have to define it explicitly. However, it is arguably better to explicitly define this so that consumers know for sure whether this is available.
Extending a standard type
The props type can extend a standard type:
interface Props  extends React.InputHTMLAttributes<    HTMLInputElement  > {  label: string;  text: string;  onTextChange: (text: string) => void;}In the above example, we have extended the standard props type for an input element. This means our component now accepts props such as maxLength and placeholder.
Alternatively we can use a type alias and intersection to achieve the same effect:
type Props = React.InputHTMLAttributes<  HTMLInputElement> & {  label: string;  text: string;  onTextChange: (text: string) => void;};Learn React with TypeScript - 3rd Edition
NewA comprehensive guide to building modern React applications with TypeScript. Learn best practices, advanced patterns, and real-world development techniques.
View on Amazon