
Các kiểu dữ liệu thường gặp trong TypeScript
25 June, 2025Module 2 - Các kiểu thường gặp trong TypeScript
- Bài viết này nằm trong khuôn khổ của: Bài 2 - Dựng khung dự án website bán thẻ Pokemon.
Bạn nào chưa đọc thì có thể đọc tại đây.
Trong bài viết trước, chúng ta đã cùng tìm hiểu về những lợi ích cơ bản của TypeScript và cách nó giúp chúng ta viết code an toàn, dễ bảo trì hơn. Hôm nay, tôi muốn đi sâu hơn vào Module 2 của loạt bài "Dựng khung dự án", nơi chúng ta sẽ khám phá các kiểu dữ liệu thường gặp trong TypeScript. Việc nắm vững các kiểu này là chìa khóa để tận dụng tối đa sức mạnh của TypeScript trong việc phát triển ứng dụng.
1. Các Kiểu Dữ Liệu Nguyên Thủy (Primitive Types)
Cũng như hầu hết các ngôn ngữ lập trình kh ác, TypeScript hỗ trợ các kiểu dữ liệu nguyên thủy quen thuộc:
string: Dùng cho văn bản, chuỗi ký tự (ví dụ:"Hello World!").number: Dùng cho số, bao gồm cả số nguyên và số thập phân (ví dụ:10,3.14).boolean: Dùng cho giá trị đúng/sai (ví dụ:true,false).
Đây là những viên gạch đầu tiên để xây dựng mọi cấu trúc dữ liệu phức tạp hơn.
2. Mảng (Arrays)
Mảng trong TypeScript được định nghĩa rõ ràng để chứa các tập hợp dữ liệu cùng một kiểu. Điều này giúp ngăn chặn việc thêm các phần tử không đúng kiểu vào mảng.
- Cú pháp: Bạn sử dụng kiểu của các phần tử, theo sau là
[](cặp ngoặc vuông). - Ví dụ:
let numbers: number[] = [1, 2, 3]hoặclet names: string[] = ["Alice", "Bob"]
3. Kiểu Bất Kỳ (Any)
Kiểu any là một kiểu dữ liệu đặc biệt cho phép bạn gán bất kỳ giá trị nào cho biến mà không cần kiểm tra kiểu. Nó mang lại sự linh hoạt như JavaScript thuần túy nhưng cũng tiềm ẩn rủi ro nếu không sử dụng cẩn thận.
- Bạn có thể gán
anycho bất kỳ kiểu dữ liệu nào, và ngược lại. - Cảnh báo: Việc sử dụng
anynên được hạn chế vì nó bỏ qua quá trình kiểm tra kiểu của TypeScript, làm mất đi lợi ích lớn nhất của việc sử dụng ngôn ngữ này – khả năng phát hiện lỗi sớm. Chỉ sử dụng khi bạn thực sự không thể xác định kiểu hoặc khi làm việc với các thư viện không có định nghĩa kiểu TypeScript.
4. Chú Thích Kiểu Trên Các Biến (Type Annotations on Variables)
Khi khai báo biến (sử dụng const, let, var), bạn có thể thêm chú thích kiểu để chỉ rõ kiểu dữ liệu mà biến đó sẽ chứa.
- Cú pháp:
let variableName: Type - Ví dụ:
let myName: string = "Zeedvn" - Lưu ý: TypeScript không cho phép khai báo kiểu bên trái tên biến (giống C++), mà chỉ cho phép khai báo kiểu bên phải. Tuy nhiên, nếu bạn không chú thích kiểu, TypeScript vẫn sẽ cố gắng suy luận kiểu của biến (Type Inference), nhưng đôi khi sự suy luận này không đủ để đảm bảo an toàn.
5. Hàm (Functions)
TypeScript cho phép chúng ta định nghĩa kiểu dữ liệu cho cả tham số đầu vào và giá trị trả về của hàm, giúp đảm bảo tính đúng đắn của logic.
- Tham số: Thêm chú thích kiểu sau tên tham số:
function greet(name: string): void { ... } - Giá trị trả về: Thêm chú thích kiểu sau dấu đóng ngoặc đơn của tham số và dấu
=>hoặc:nếu hàm có thân hàm:function add(a: number, b: number): number { return a + b; } - Hàm trả về Promise: Sử dụng
Promise<Type>để định nghĩa kiểu dữ liệu mà Promise sẽ trả về:async function fetchData(): Promise<string> { ... }
6. Hàm Vô Danh (Anonymous Functions)
Hàm vô danh (anonymous function) là các hàm không có tên, thường được sử dụng làm callback. TypeScript có thể tự động suy luận kiểu của các tham số và giá trị trả về của hàm vô danh dựa trên ngữ cảnh mà nó được gọi.
Ví dụ:
7. Kiểu Đối Tượng (Object Types)
Kiểu đối tượng mô tả cấu trúc của một object, bao gồm các thuộc tính và kiểu dữ liệu tương ứng của chúng.
Cú pháp
Thuộc tính tùy chọn (?): Bạn có thể đánh dấu một thuộc tính là không bắt buộc bằng cách thêm dấu ? sau tên thuộc tính.
8. Kiểu Hợp Nhất (Union Types)
Kiểu hợp nhất cho phép một biến hoặc tham số có thể chứa nhiều kiểu dữ liệu khác nhau.
- Cú pháp: Sử dụng dấu
|giữa các kiểu. - Ví dụ:
let id: number | string = 123hoặcfunction printId(id: number | string) { ... } - Lưu ý: Khi làm việc với Union Types, bạn cần thu hẹp kiểu (type narrowing) bằng cách kiểm tra kiểu của biến để đảm bảo an toàn.
9. Kiểu Bí Danh (Type Aliases)
Kiểu bí danh cho phép bạn đặt một tên mới cho một kiểu dữ liệu hiện có, bao gồm cả các kiểu nguyên thủy, kiểu đối tượng, và Union Types.
- Cú pháp:
type NewTypeName = ExistingType - Ví dụ:
type ID = number | string
10. Interfaces
Interface là một công cụ mạnh mẽ để định nghĩa cấu trúc của các đối tượng. Nó tương tự như type aliases cho object types nhưng có một số khác biệt chính, đặc biệt là trong việc kế thừa và triển khai.
Ví dụ
- Điểm khác biệt chính giữa Type Aliases và Interfaces: Mặc dù có nhiều điểm tương đồng, Interface có thể được implement bởi class, trong khi Type Alias thì không. Interface hỗ trợ kế thừa (extension) và có thể được sử dụng để định nghĩa hợp đồng cho các class.
11. Các Kiểu Xác Nhận (Type Assertions)
Đôi khi, bạn có thông tin về kiểu của một giá trị mà TypeScript không thể tự động suy luận. Trong những trường hợp này, bạn có thể sử dụng Type Assertions để "xác nhận" với trình biên dịch rằng bạn biết kiểu chính xác của giá trị đó.
- Cú pháp:
(<Type>value)(value as Type)
- Ví dụ:
const myCanvas = document.getElementById('main_canvas') as HTMLCanvasElement - Lưu ý: Type Assertions không ảnh hưởng đến code khi chạy. Nó chỉ là một tín hiệu cho trình biên dịch để bỏ qua kiểm tra kiểu ở thời điểm biên dịch.
12. Kiểu Phân Tách (Literal Types) & Suy Luận Kiểu (Literal Inference)
- Literal Types: Cho phép bạn định nghĩa các kiểu dữ liệu chỉ chấp nhận một giá trị cố định, thường là chuỗi, số hoặc boolean.
- Ví dụ:
let alignment: "left" | "right" | "center"
- Ví dụ:
- Literal Inference: Khi bạn khởi tạo một thuộc tính cho một đối tượng, TypeScript có thể suy luận rằng thuộc tính đó có thể thay đổi giá trị. Tuy nhiên, bạn có thể kiểm soát hành vi này để tạo ra các kiểu Literal nghiêm ngặt hơn.
13. null và undefined
-
Trong JavaScript,
nullvàundefinedđều đại diện cho các giá trị vắng mặt, và cả hai đều có thể gán cho bất kỳ kiểu dữ tính nào. -
strictNullChecks: Đây là một chế độ nghiêm ngặt trong TypeScript. Khi bật chế độ này, bạn sẽ cần phải kiểm tra rõ ràng các giá trịnullhoặcundefinedtrước khi truy cập các thuộc tính hoặc phương thức trên chúng.
- Toán tử Non-null Assertion (
!): Một cú pháp đặc biệt cho phép bạn "khẳng định" rằng một giá trị không phải lànullhoặcundefined.- Ví dụ:
let x: string | null = "Hello"; console.log(x!.toUpperCase())// Dấu!đảm bảo x không phải null.
- Ví dụ:
Việc nắm vững các kiểu dữ liệu này là nền tảng để bạn có thể viết code TypeScript hiệu quả, đáng tin cậy và dễ bảo trì. Đây là những kiến thức cốt lõi sẽ đồng hành cùng bạn trong mọi dự án lớn nhỏ.
Trong quá trình thực hiện dự án này không may có sai sót, rất mong nhận được sự góp ý từ các bạn để mình có thể hoàn thiện hơn trong tương lai.
Hẹn gặp lại trong bài viết tiếp theo, nơi chúng ta sẽ khám phá sâu hơn về cách TypeScript làm việc với hàm!
Chúc các bạn học tập và làm việc hiệu quả!
