Typing Props with TypeScript
Describe the shape of your props with a TypeScript type or interface.
Syntax
type Props = { name: string; age?: number };In modern React, TypeScript is the standard way to document and check props. You declare a type describing each prop, and your editor warns you if a required prop is missing or the wrong type.
How it works
- Define a
typeorinterfacefor the props. - Annotate the component's parameter with it.
- Mark optional props with
?and give defaults as usual.
The legacy prop-types package still exists for plain JavaScript projects, but TypeScript is the recommended approach for React 19.
Example
type GreetingProps = {
name: string;
age?: number;
children?: React.ReactNode;
};
function Greeting({ name, age = 0, children }: GreetingProps) {
return (
<div>
<p>{name} is {age} years old.</p>
{children}
</div>
);
}
export default Greeting;When to use it
- A design system uses TypeScript interfaces for every component's props so editors show autocomplete and flag wrong types before the component is even rendered.
- A cross-team contract enforces that the API layer's data shape and a component's prop type share the same TypeScript type, catching schema drift at compile time.
- A refactoring of a large codebase uses TypeScript to audit which optional props are actually always provided so the team can safely make them required.
More examples
Basic typed props
Defines a TypeScript type for the props, making label and onClick required and disabled optional with a default.
type ButtonProps = {
label: string;
onClick: () => void;
disabled?: boolean;
};
function Button({ label, onClick, disabled = false }: ButtonProps) {
return (
<button onClick={onClick} disabled={disabled}>
{label}
</button>
);
}Interface with union type prop
Uses a union type to restrict the variant prop to one of three valid string literals, caught at compile time if violated.
interface AlertProps {
message: string;
variant: 'info' | 'warning' | 'error';
}
function Alert({ message, variant }: AlertProps) {
return (
<div className={`alert alert--${variant}`} role="alert">
{message}
</div>
);
}Typing children and event props
Types the onChange event handler with the precise DOM event type and accepts optional children typed as ReactNode.
import { ReactNode, ChangeEvent } from 'react';
type FormFieldProps = {
label: string;
value: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
children?: ReactNode;
};
function FormField({ label, value, onChange, children }: FormFieldProps) {
return (
<label>
{label}
<input value={value} onChange={onChange} />
{children}
</label>
);
}
Discussion