Common
Both can define a data type.
Types aliases in Typescript mean “a new for any type”.
type StringOrNumber = string | number;
type User = {
id: number;
name: string;
email: string;
}
An interface defines a contract that an object must adhere to.
name: string;
address: string;
}
Difference
1. Primitive Type
Primitive types are inbuilt types in TypeScripts. They include number, string, boolean, null, and undefined types.
Type alias can be used to define a alias for a primitive type as below.
type NullOrUndefined = null | undefined;
But, interface can not be used to define a alias for a primitive type.
2. Union types
Union types can describe values that can be one of several constant and create unions of various primitive, literal or complex types.
Union type can only be defined using type. Interface cannot define a union type. But it is possible to create a new union type from several interfaces:
cpu: string;
ram: number;
storage: number;
}
interface SmartPhone {
number: string;
}
type Mobile = Laptop | Phone;
3. Function types
In Typescript, a function type represents a function’s prototype. Type alias defines function prototype like this:
You can also use an interface to do samething:
(num: number, num2: number): number;
}
As you can see both type and interface are similar except for a syntax difference. And type is preferred to define a function prototype.
It is also because type has more capability to define function type. Here’s an example:
type WindUp = (cycle: number) => void;
type Recharge = () => void;
type RefillWatch<W extends Watch> =
W extends ‘Mechanical‘ ?
WindUp : W extends ‘Electrical‘ ?
Recharge : never;
const windUp: RefillWatch<‘Mechanical‘> = (watch, cycle) => {
// Something to wind up the spring of the watch
}
const recharge: RefillWatch<‘Electrical‘> = (watch) => {
// Something to charge the watch
}
4. Merging of declarations
Merging of declarations is a feature for only interface.
cpu: string;
}
interface Computer {
ram: string;
}
const mine: Computer = {
cpu: ‘Core i-9 9900‘,
ram: ‘32GB‘,
};
5. Extends and intersection
An interface can extend original interface:
cpu: string;
ram: string;
}
interface Laptop extends Computer {
battery: string;
}
You can also get same result with type alias:
cpu: string;
ram: string;
}
type Laptop = Computer & {
battery: string;
}
You can also extends an interface from a type alias:
cpu: string;
ram: string;
}
interface Laptop extends Computer {
battery: string;
}
But you cannot extend an interface from a union type:
interface MoreWatch extends Watch {
brand: string;
}
Type aliases can extend interfaces using the intersection like this:
brand: string;
}
Type ElectricWatch = Watch & {
battery: string;
}
6. Handling conflicts
You cannot extend an interface with same property key like this:
refill: () => void;
}
interface Watch {
refill: (cycle: number) => void;
}
But you can extend a type alias with same property key like this:
getPermission: (id: string) => string;
};
type Staff = Person & {
getPermission: (id: string[]) => string[];
};
const AdminStaff: Staff = {
getPermission: (id: string | string[]) => {
return (typeof id === ‘string‘ ?
‘admin‘ : [‘admin‘]) as string[] & string;
}
}
If you extend a type alias like this, the model property type would not be determined because it can’t be both string and number at the same time:
model: string;
};
type Laptop = Computer & {
model: number;
};
// error: Type ‘string’ is not assignable to type ‘never’.(2322)
const mine: Laptop = { model: ‘Dell‘ };
7. Implementing class
In Typescript, you can implement a class using either an interface or a type alias:
name: string;
greet(): void;
}
class Student implements Person {
name: string;
greet() {
console.log(‘Hello‘);
}
}
type Pet = {
name: string;
greet(): void;
};
class Cat implements Pet {
name: string;
greet() {
console.log(‘Mew‘);
}
}
But you cannot implement a class that extends a union type:
// can not implement a union type
class PrimaryKey implements Key {
key = 1
}
8. Tuple type
In Typescript, the tuple type can express an array with a fixed number of elements, while each element has its data type:
If you want to declare a tuple type with an interface, you can do it like this:
0: string;
1: (value: string) => void;
}
9. Benefits of the type alias than the interface
Here’s an example of the advanced type feature that the interface cannot achieve:
name: string;
address: string;
}
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type PersonType = Getters<Perso>;
// type PersonType = {
// getName: () => string;
// getAddress: () => string;
// }
Conclusion
In this post, I have explained the features of the type alias and the interface in Typescript.
As above the type alias has more powerful features than the interface. So I recommend to use the type alias when coding.