Types and Interfaces
What are Types and Interfaces?
Types and interfaces both let you describe the shape of an object.
In React, we often use them for declaring props, state, API responses, and config objects.
// Using type
type User = {
id: string;
name: string;
age?: number; // optional
};
// Using interface
interface Product {
id: number;
title: string;
}
When to Use What?
Interface
Use interface
when you're working with object-like structures such as props and API response types.
Interfaces can be extended using extends
, making it easy to reuse and compose types in a clean, modular way.
interface User {
id: string;
name: string;
age?: number; // Optional
}
// Extend User to include email for registered users
interface RegisteredUser extends User {
email: string;
isVerified: boolean;
}
const guestUser: User = {
id: "guest-01",
name: "Guest"
};
const registeredUser: RegisteredUser = {
id: "user-123",
name: "Alice",
age: 25,
email: "[email protected]",
isVerified: true
};
💡 React Tip: Prefer
interface
for component props because they’re extendable.
Type
Use type
for unions, primitives, or when combining complex types.
Union Types
type Status = 'loading' | 'success' | 'error'; // union type
const showStatus = (status: Status) : void => {
if (status === 'loading') {
console.log('Please wait...');
}
}
showStatus('loading'); // "Please wait..."
showStatus('success'); // Print nothing
Discriminated Unions (Tagged Unions)
Useful for modeling variants like UI components and API states.
type TextInput = { type: 'text'; placeholder: string };
type CheckboxInput = { type: 'checkbox'; checked: boolean };
// Now the FormInput takes in either TextInput or CheckboxInput
type FormInput = TextInput | CheckboxInput;
const renderInput = (input: FormInput) : JSX.Element => {
// render the input based on the type accordingly
if (input.type === 'text') {
return <input type="text" placeholder={input.placeholder} />;
}
return <input type="checkbox" checked={input.checked} />;
}
Function Types
type Callback = (value: string) => void;
const onChange: Callback = (val) => {
console.log('Changed:', val);
};
This is often used in props like onClick
, onSubmit
, or custom event handlers in React components.
Tuple Types
type NameAndAge = [string, number];
const person: NameAndAge = ['Alice', 30];
// Destructuring
const [name, age] = person;
Tuples are great because they allow each element in the array to be a known type of value.
Mapped Types with type
type Keys = 'title' | 'description';
type FieldMap = {
[K in Keys]: string;
};
// Same as:
// type FieldMap = {
// title: string;
// description: string;
// };
Combining Types with & (Intersection)
type WithTimestamp = { createdAt: Date; updatedAt: Date };
type Post = { id: string; content: string };
type PostWithTimeStamp = Post & WithTimestamp;
const post: PostWithTimeStamp = {
id: 'p1',
content: 'Hello world!',
createdAt: new Date(),
updatedAt: new Date()
};
Last updated