Trong TypeScript, cả type
và interface
đều được sử dụng để định nghĩa các kiểu dữ liệu. Tuy nhiên, chúng có những khác biệt quan trọng về cách sử dụng, khả năng mở rộng, và tính năng. Hiểu rõ sự khác biệt giữa type
và interface
sẽ giúp bạn chọn lựa công cụ phù hợp cho các nhu cầu khác nhau trong lập trình. Bài viết này sẽ phân tích những điểm khác biệt này một cách chi tiết.
Khái niệm cơ bản về type và interface
1. Type
type
là một từ khóa trong TypeScript cho phép bạn định nghĩa các kiểu dữ liệu, bao gồm cả kiểu nguyên thủy, kiểu đối tượng, kiểu hàm, và nhiều kiểu khác.
type User = {
name: string;
age: number;
};
2. Interface
interface
là một cách khác để định nghĩa kiểu dữ liệu, thường được sử dụng để mô tả cấu trúc của các đối tượng. interface
cũng hỗ trợ tính kế thừa và mở rộng.
interface User {
name: string;
age: number;
}
Sự khác biệt giữa type và interface
1. Khả năng mở rộng
Một trong những điểm khác biệt chính giữa type
và interface
là khả năng mở rộng.
- Interface có thể được mở rộng nhiều lần, nghĩa là bạn có thể khai báo lại cùng một tên
interface
và thêm các thuộc tính mới.
interface User {
name: string;
}
interface User {
age: number;
}
// Kết quả là User có cả name và age
const user: User = {
name: 'Alice',
age: 25,
};
- Type không thể được mở rộng như vậy. Nếu bạn cố gắng khai báo lại cùng một tên, TypeScript sẽ báo lỗi.
type User = {
name: string;
};
// Nếu bạn cố gắng khai báo lại
type User = {
age: number;
}; // Lỗi: Duplicate identifier 'User'.
2. Tính kế thừa
Cả type
và interface
đều hỗ trợ tính kế thừa, nhưng cách thức thực hiện khác nhau.
- Interface sử dụng từ khóa
extends
để kế thừa từ một hoặc nhiều interface
khác.
interface Person {
name: string;
}
interface User extends Person {
age: number;
}
- Type có thể sử dụng phép giao (
&
) để kết hợp nhiều kiểu.
type Person = {
name: string;
};
type User = Person & {
age: number;
};
3. Kiểu hàm
Cả hai đều có thể được sử dụng để định nghĩa kiểu hàm, nhưng cú pháp hơi khác nhau.
- Type cho phép bạn định nghĩa kiểu hàm như sau:
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
- Interface cũng cho phép định nghĩa kiểu hàm nhưng với cú pháp khác:
interface Add {
(a: number, b: number): number;
}
const add: Add = (a, b) => a + b;
4. Khả năng kết hợp với các kiểu khác
- Type có thể định nghĩa kiểu cho các loại dữ liệu khác nhau như union types, tuple types, v.v.
type StringOrNumber = string | number;
- Interface không hỗ trợ kết hợp như vậy, nó chủ yếu được sử dụng để định nghĩa các đối tượng.
5. Tính tương thích cấu trúc
Cả type
và interface
đều dựa trên tính tương thích cấu trúc. Điều này có nghĩa là bạn có thể sử dụng một đối tượng có cấu trúc tương tự như một interface
hoặc type
mà không cần phải định nghĩa chính xác kiểu.
type User = {
name: string;
age: number;
};
const user = {
name: 'Alice',
age: 25,
address: '123 Main St',
};
// user có thể được sử dụng như User
const displayUser = (user: User) => {
console.log(user.name);
};
displayUser(user); // "Alice"
Kết luận
Sự khác biệt giữa type
và interface
trong TypeScript chủ yếu nằm ở khả năng mở rộng, tính kế thừa, và khả năng định nghĩa kiểu cho các loại dữ liệu khác nhau. interface
thường được ưa chuộng hơn khi bạn cần định nghĩa cấu trúc cho các đối tượng, trong khi type
cung cấp tính linh hoạt hơn cho các kiểu dữ liệu phức tạp. Hiểu rõ các khác biệt này sẽ giúp bạn chọn lựa công cụ phù hợp cho nhu cầu cụ thể của dự án, từ đó cải thiện chất lượng mã nguồn và khả năng bảo trì.