Let's talk about the difference between Type and Interface in Typescript, In the latest versions of Typescript, the differences between them are minimal, and Type now can be used over interface in almost all cases.
Both Interface and Type can be used to describe the properties of an object or a function signature. But the syntax differs
// interface
interface IUser {
id: number;
firstName: string;
lastName: string;
}
const user: IUser = {
id: 1,
firtName: 'Saif',
lastName: 'Adnan'
};
// type
type TUser = {
id: number;
firstName: string;
lastName: string;
};
const user: TUser = {
id: 1,
firtName: 'Saif',
lastName: 'Adnan'
};
As it is clear from the sample above, for object declaration there is no difference between them except for syntax changes. Interface syntax is like Class declaration and Type is like object declaration.
class User {}
interface IUser {
id: number;
firstName: string;
lastName: string;
}
const object = {};
type TUser = {
id: number;
firstName: string;
lastName: string
};
Type and Interface both can be used for function signature, see the example below:
interface IGetUserFullName {
(user: IUser): string;
}
const getUserFullName: IGetUserFullName = (user) => `${user.firstName} ${user.lastName}`;
type TGetUserFullName = (user: TUser) => string;
const getUserFullName: TGetUserFullName = (user) => `${user.firstName} ${user.lastName}`;
Starting Typescript 2.2, It's now possible to have an interface that extends object like type Now It's possible that Interface can extend a Type
type TAddress = {
city: string;
country: string;
}
interface IUser extends TAddress {}
const user: IUser = {
city: 'Malvern',
country: 'USA'
}
Now let's see what features does the Type has that Interface does not
- Primitive Alias using Type we can create an alias for some primitive value, for example alias for unique ID, and use it in other interfaces or types for more meaningful and understandable code.
type UniqueId = string;
interface User {
id: UniqueId;
}
If alias is not for a primitive value, but for an array, then we can use either type or interface
type TRoles = string[];
interface IRoles {
[key: number]: string;
}
2.Tuples allow use to use this new data type that includes two sets of values of different data types Tuple: is an array of a unchanged size and act as a constant in the world of arrays
type Employee = [number, string]
const elon: Employee = [1, 'Elon']
- Intersection allow us to combine multiple types into a single one type. To create an intersection type, we have to use the & keyword:
type Name = {
name: string
}
type Age = {
age: number;
}
type Person = Name & Age;
const elon: Person = {
name: 'Elon',
age: 22
}
- Union allow use to create a new type that can have a value of one or a few more types. To create a union type, we have to use the | keyword:
type A = {
age: number;
}
type B = {
name: string;
}
type C = A | B;
// define only name
const andrew: C = {
name: 'Andrew'
}
// define only age
const justin: C = {
age: 25
}
// or we can define both fields
const kelly: C = {
name: 'Kelly',
age: 29
}
- Auto merge works only with Interface. If type get declared multiple times the typescript compiler throws an error.
type A = {
name: string
}
type A = {
age: number
}
//Typescript compiler throws errors => Duplicate identifier 'A'
Typescript merges the two declarations for Interface
interface B {
name: string;
}
interface B {
age: number;
}
const bob: B = {
name: 'Bob',
age: 40
};
Conclusion In this article, we have discussed the main differences between types and interfaces. They are very similar, but what you should use depends on your use case.
For public API definitions in a library or third-party type definition, an interface should be used to provide declaration merging capabilities.
Apart from that, we can use whatever we want, but there should be consistency across the codebase.