- Published on
Day15: Learning TypeScript: Interface VS Type Aliases
- Authors

- Name
- irisjustdoit
- @irisjustdoit
Day15: Learning TypeScript: Interface VS Type Aliases
In the previous article, we discussed interfaces; today we will talk about type aliases. They have very similar functionalities, but there are still some differences. Let's take a look. Before that, let's introduce Type Aliases.
Type Aliases
Type aliases are used to give a type a new name. The syntax for declaring a type alias is to use the type keyword. They are commonly used for union types, but they can also define objects and functions, just like interfaces. Below, we will introduce their differences.
A type alias is exactly that - a name for any type.
For example, the id type is somewhat repetitive:
const printId = (id: string | number) => {
console.log(`my id is ${id}`)
}
const sayHi = (person: { name: string, id: string | number }) => {
console.log(`hi, ${person.name}! your id is ${id}.`)
}
At this point, we can use type aliases to define the type of string | number, helping us simplify the code and allowing the type to be shared. Isn't it much neater and easier to maintain later?
type StringOrNum = string | number;
type objWithName = { name: string, id: StringOrNum };
const printId = (id: StringOrNum) => {
console.log(`${name} id is ${id}`)
}
const sayHi = (person: objWithName) => {
console.log(`hi, ${person.name}! your id is ${id}.`)
}
Type Aliases vs Interfaces
As mentioned earlier, their functionalities are very similar. Let's take a look at their similarities and differences:
Similarities 1: Both can define the shape of objects (object, function, array)
Both can use readonly / optional properties / add arbitrary properties / function overloads.
Interface:
// Object
interface IUser {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
getWeight(): number;
getWeight(x?: number): number;
}
// Function
interface SetPoint {
(x: number, y: number): void;
}
// Array
interface NumberArray {
[index: number]: number;
}
Type:
// Object
type User = {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
getWeight(): number;
getWeight(x?: number): number;
}
// Function
type SetPoint = (x: number, y: number) => void;
// Array
type NumberArray = {
[index: number]: number;
}
Similarities 2: Both can extend, but the usage is different
Extending an interface:
interface Animal {
name: string;
}
interface Bear extends Animal {
honey: boolean;
}
Extending a type via intersections:
type Animal = {
name: string;
}
type Bear = Animal & {
honey: boolean;
}
Interface extends type:
type Name = {
name: string;
}
interface User extends Name {
age: number;
}
Differences 1: Type Aliases can represent primitive types, union types, and tuples
Type aliases can represent primitive types, union types, and tuples, while interfaces cannot.
type StringOrNum = string | number;
type Point = [number, number];
Differences 2: Interfaces can be merged
If you define the same interface multiple times, TypeScript will merge them into a single interface.
interface User {
name: string;
}
interface User {
age: number;
}
// Merged interface
const user: User = {
name: "John",
age: 30,
};
Type aliases cannot be merged:
type User = {
name: string;
};
type User = {
age: number;
}; // Error: Duplicate identifier 'User'.
In conclusion, both interfaces and type aliases are powerful tools in TypeScript, and understanding their differences can help you choose the right one for your needs. In the next article, we will continue exploring more TypeScript features. See you tomorrow!
References
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases https://www.typescriptlang.org/docs/handbook/2/objects.html#interfaces
