Why I Always Choose to Use Types Instead of Interfaces？
Tags: interfacesegregation, typescript, webdev, javascript
Published: 2024-06-24 05:12:09

In TypeScript, both Types and Interfaces are used to define the types of objects. However, they have different uses and features. Both can help developers constrain the types of variables and objects when writing code, thereby reducing errors and improving code readability.

-   **_type:_** `type` is a type alias used to define an alias for any type. This is not limited to object types; it can also define primitive types, union types, intersection types, etc. For example:

// Define an alias for a primitive type  
```
type Name = string;  
  
// Define an alias for an object type  
type User = {  
  id: number;  
  name: string;  
}; 
  
// Define a union type  
type Status = 'active' | 'inactive' | 'suspended';  
  
// Define an intersection type  
type Person = {  
  name: string;  
} & {  
  age: number;  
};
``` 

-   **interface:** `interface` is used to define the structure of an object and can be extended by inheriting other interfaces. `interface` is mainly used to define the structure and implementation constraints of classes. For example:
```
// Define an object interface  
interface User {  
  id: number;  
  name: string;  
}  
  
// Interface inheritance  
interface Admin extends User {  
  role: string;  
}  
  
// Interface implementation in a class  
class Person implements User {  
  id: number;  
  name: string;  
    
  constructor(id: number, name: string) {  
    this.id = id;  
    this.name = name;  
  }  
}
```
# Why prioritize using Types?

In TypeScript, there has been an ongoing debate about whether to use Types or Interfaces for type definitions. Although both can be used to create reusable structures for variables, function parameters, and return values, in most cases, we should prioritize using Types. Here are four main reasons:

## **1\.** Support for Union Types

`type` can define union types, which is something `interface` cannot do.
```
type StringOrNumber = string | number;
```
## **2\.** Support for String Literal Types
```
`type` can define string literal types, which can be very useful in certain scenarios.

type Status = 'success' | 'error' | 'pending';

## **3\.** Immutability

`type` is immutable, meaning once defined, it cannot be changed through extension or merging. This ensures the stability and consistency of the type. In contrast, `interface` can be declared multiple times and merged, which might lead to unexpected behaviors.
type User = {  
    email: string;  
}
// Will cause an error because it cannot be declared multiple times  
type User = {  
    password: string;  
}  
interface User {  
    email: string;  
}  

// The two declarations will be merged, and the final User interface will contain both email and password properties.  
interface User {  
    password: string;  
}
```

## **4\.** Support for Conditional Types

`type` supports conditional types, which can be used for more complex type definitions.
```
type IsString<T> = T extends string ? 'yes' : 'no';
```
In summary, prioritizing `type` provides greater flexibility and powerful type expression capabilities, especially when dealing with complex types and logic. `type` can better meet your needs. Therefore, I always choose to use `type` first, as it enhances code type safety and maintainability.