In TypeScript, both `type` and `interface` can be used to define shapes for objects, but there are some differences and use cases for each. Here’s a breakdown of when to use each:
### Use Cases for `interface`
1. **Extensibility**: Interfaces are designed to be extendable. You can use `extends` to create new interfaces based on existing ones, allowing for a clear inheritance structure.
```typescript
interface User {
email: string;
admin: boolean;
}
interface AdminUser extends User {
accessLevel: number;
}
```
2. **Merging Declarations**: Interfaces can be declared multiple times, and TypeScript will merge them. This is useful for augmenting types from libraries or when you want to add additional properties to an existing interface.
```typescript
interface User {
email: string;
}
interface User {
admin: boolean;
}
// Merged into:
// interface User {
// email: string;
// admin: boolean;
// }
```
3. **Use in Class Definitions**: Interfaces are often preferred for defining the structure of classes because they can be implemented by classes.
```typescript
interface IUser {
email: string;
admin: boolean;
}
class User implements IUser {
constructor(public email: string, public admin: boolean) {}
}
```
### Use Cases for `type`
1. **Union Types**: Types can represent union types, which allow you to specify that a value can be one of several types.
```typescript
type Status = 'active' | 'inactive' | 'pending';
```
2. **Tuples and More Complex Types**: You can use types to create tuples or to define more complex shapes, including combinations of objects, unions, and intersections.
```typescript
type Point = [number, number]; // Tuple type
```
3. **Aliases for Primitive Types**: You can create aliases for primitive types, making the code more readable.
```typescript
type ID = string; // Alias for string
```
#### Defining the shape of an object
Both `type` and `interface` can often be used interchangeably for defining object shapes, so the choice may come down to personal or team preference.
### Summary
- Use **`interface`** when you want to define a contract for classes, take advantage of extensibility, or leverage declaration merging.
- Use **`type`** when you need union types, tuples, or when you want to create more complex types that may not fit neatly into the object-oriented paradigm.