TypeScript cơ bản – Type và interface: mô tả cấu trúc dữ liệu
- 17-10-2026
- Toanngo92
- 0 Comments
Viết cấu trúc object ngay cạnh từng biến phù hợp với ví dụ nhỏ, nhưng sẽ lặp lại khi nhiều hàm cùng xử lý khóa học hoặc học viên. Type và interface cho phép đặt tên cho những cấu trúc đó. Bài này nối tiếp kiến thức object, array và union đã có trong chuyên mục.
Mục lục
1. Đặt tên kiểu bằng type
type CourseLevel = "beginner" | "advanced";
type CourseSummary = {
id: number;
title: string;
level: CourseLevel;
};
const summary: CourseSummary = {
id: 1,
title: "TypeScript cơ bản",
level: "beginner"
};
CourseLevel chỉ chấp nhận hai giá trị chuỗi đã liệt kê, thay vì mọi string. Type alias cũng có thể đặt tên cho union, tuple, kiểu hàm và nhiều biểu thức kiểu khác. Đặt tên theo khái niệm của ứng dụng giúp người đọc hiểu dữ liệu được dùng để làm gì.
2. Mô tả object bằng interface
interface Course {
readonly id: number;
title: string;
description?: string;
level: "beginner" | "advanced";
}
const course: Course = {
id: 1,
title: "TypeScript cơ bản",
level: "beginner"
};
console.log(course.description?.trim() ?? "Chưa có mô tả");
Thuộc tính description có dấu ? nên có thể được bỏ qua. Khi đọc, cần tính đến undefined. Với cấu hình strict ở loạt bài này, truy cập thẳng description.trim() sẽ bị cảnh báo. Dấu ?. chỉ gọi trim khi có giá trị, còn ?? cung cấp nội dung thay thế khi kết quả là null hoặc undefined.
readonly id ngăn gán lại id thông qua kiểu Course trong quá trình kiểm tra kiểu. Nó không đóng băng object khi chạy, cũng không làm mọi object lồng nhau trở thành bất biến. const ngăn gán lại biến; readonly kiểm soát việc ghi thuộc tính qua một kiểu cụ thể.
3. Mở rộng interface và kết hợp type
interface PublishedCourse extends Course {
publishedAt: string;
}
type CourseWithLessons = Course & {
lessonCount: number;
};
const published: PublishedCourse = {
...course,
publishedAt: "2026-10-17"
};
const detail: CourseWithLessons = {
...course,
lessonCount: 13
};
Extends tạo interface dựa trên cấu trúc đã có. Dấu & yêu cầu dữ liệu thỏa mãn đồng thời các kiểu được kết hợp. Nếu hai thuộc tính cùng tên có kiểu không tương thích, intersection có thể tạo ra một kiểu không thể đáp ứng; đừng dùng nó để che giấu xung đột trong mô hình dữ liệu.
4. Type hay interface?
Cả hai đều mô tả được nhiều cấu trúc object thông thường. Interface thuận tiện khi mở rộng cấu trúc và có cơ chế gộp các khai báo cùng tên. Type alias linh hoạt với union, tuple và các phép biến đổi kiểu, nhưng không được khai báo lại cùng tên trong cùng phạm vi. Trong một dự án, quy ước nhất quán quan trọng hơn việc cố thay mọi type thành interface hoặc ngược lại.
5. TypeScript kiểm tra theo cấu trúc
function printCourse(item: Course): void {
console.log(item.title);
}
printCourse(published); // Có đủ các thuộc tính mà Course yêu cầu
Một giá trị không bắt buộc phải xuất phát từ một class cụ thể mới tương thích với Course. Nó cần có cấu trúc phù hợp. Tuy vậy, object literal được gán trực tiếp thường có bước kiểm tra thuộc tính thừa, giúp phát hiện lỗi gõ như title thành tittle; không nên suy ra rằng mọi thuộc tính ngoài khai báo đều bị loại bỏ.
6. Kiểu dữ liệu không phải dữ liệu thật
Interface và type alias bị xóa khỏi đầu ra JavaScript. Khai báo interface Course không tạo sẵn một khóa học, không sinh constructor và không xác nhận JSON từ server hợp lệ. Muốn chạy ví dụ, giữ các phần khai báo cần thiết trong src/main.ts, thêm export {} rồi biên dịch theo bài cấu hình. Ở bài API, chúng ta sẽ kiểm tra cấu trúc nhận về trước khi dùng như một kiểu đã biết.
Đọc thêm: TypeScript: Everyday Types.
Đọc thêm: TypeScript: Object Types.
Đọc tiếp trong loạt bài
Bài trước: TypeScript cơ bản – Hàm, kiểu tham số, giá trị trả về và callback
Bài tiếp theo: TypeScript cơ bản – Null, undefined, narrowing và type guards

