Từ Zero đến Principal Frontend Engineer (P3: TypeScript nâng cao)

0 0 0

Người đăng: Huỳnh Trọng Thoại

Theo Viblo Asia

TypeScript Nâng Cao: Hiểu Rõ Bản Chất để Áp Dụng Đúng

Dành cho dev đã biết TypeScript cơ bản nhưng muốn hiểu sâu hơn về Generics, Decorators và Advanced Types – không chỉ biết cách dùng mà còn hiểu tại saokhi nào nên dùng.


1. Generics: "Khuôn" Để Đúc Nhiều Kiểu Dữ Liệu

Bản chất:

Generics giống như một cái khuôn (template) cho phép bạn viết code một lần nhưng dùng được cho nhiều kiểu dữ liệu khác nhau, mà vẫn đảm bảo an toàn kiểu (type safety).

Khi nào dùng?

  • Khi bạn muốn hàm/class của mình linh hoạt với nhiều kiểu dữ liệu.
  • Nhưng không muốn hy sinh type checking của TypeScript.

Ví dụ thực tế:

// ❌ Không dùng Generics → phải viết nhiều hàm
function getString(value: string): string { return value; }
function getNumber(value: number): number { return value; } // ✅ Dùng Generics → 1 hàm làm việc cho mọi kiểu
function getValue<T>(value: T): T { return value;
} const name = getValue<string>("Alice"); // Kiểu string
const age = getValue<number>(25); // Kiểu number

Giải thích:

  • Tbiến kiểu (type variable), đại diện cho kiểu dữ liệu sẽ được truyền vào.
  • Khi gọi hàm, bạn chỉ định Tstring, number, hay bất kỳ kiểu nào.

Lưu ý quan trọng:

  • Không phải lúc nào cũng cần Generics. Chỉ dùng khi bạn thực sự cần làm việc với nhiều kiểu.
  • Đừng lạm dụng – nếu chỉ làm việc với 1 kiểu cụ thể, hãy dùng kiểu trực tiếp (string, number,...).

2. Decorators: "Trang Trí" Code Để Thêm Tính Năng

Bản chất:

Decorator là hàm đặc biệt có thể "gắn" vào class, method, property để thay đổi hoặc thêm tính năng mà không cần sửa code gốc.

Khi nào dùng?

  • Khi bạn muốn áp dụng tính năng chung (log, validate, cache,...) cho nhiều class/method.
  • Tránh lặp code bằng cách tách cross-cutting concerns (logic chung) ra decorators.

Ví dụ thực tế:

// Decorator để log thời gian chạy của method
function logTime(target: any, methodName: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { console.time(methodName); const result = originalMethod.apply(this, args); console.timeEnd(methodName); return result; };
} class Calculator { @logTime // Gắn decorator vào method sum(a: number, b: number) { return a + b; }
} const calc = new Calculator();
calc.sum(1, 2); // Console sẽ hiện: "sum: 0.123ms"

Giải thích:

  • Decorator @logTime bao bọc method sum để đo thời gian chạy.
  • Không cần sửa code của sumgiữ nguyên logic chính.
  • Có thể tái sử dụng cho bất kỳ method nào khác.

Lưu ý quan trọng:

  • Không phải magic! Decorator chỉ là hàm JavaScript chạy ở runtime.
  • Cẩn thận performance nếu dùng quá nhiều decorator phức tạp.

3. Advanced Types: Kiểu Dữ Liệu "Thông Minh" Hơn

Bản chất:

TypeScript có nhiều kiểu nâng cao giúp bạn mô tả chính xác hơn cấu trúc dữ liệu, giảm bug và tăng khả năng tự động hoàn thành code.

Khi nào dùng?

  • Khi bạn muốn kiểm soát chặt chẽ kiểu dữ liệu đầu vào/đầu ra.
  • Khi làm việc với dữ liệu phức tạp (API response, Redux state,...).

Ví dụ thực tế:

Union Types (|): "Hoặc cái này, hoặc cái kia"

type Status = "success" | "error" | "loading"; function handleStatus(status: Status) { if (status === "success") { console.log("Thành công!"); } else if (status === "error") { console.log("Lỗi!"); }
} handleStatus("success"); // OK
handleStatus("pending"); // ❌ Lỗi: "pending" không nằm trong kiểu Status

Type Guards: Kiểm tra kiểu tại runtime

interface User { name: string; age: number;
} function isUser(obj: any): obj is User { return obj && typeof obj.name === "string" && typeof obj.age === "number";
} const data = JSON.parse('{"name":"Alice","age":25}'); if (isUser(data)) { console.log(data.name); // TypeScript "biết" data là User
}

Lưu ý quan trọng:

  • Đừng làm phức tạp quá. Nếu kiểu quá phức tạp, hãy cân nhắc refactor code.
  • Dùng unknown thay cho any khi làm việc với dữ liệu động để an toàn hơn.

Kết Luận: Khi Nào Dùng Gì?

Tính năng Khi nào dùng? Ví dụ thực tế
Generics Code làm việc với nhiều kiểu dữ liệu API service, hàm utility
Decorators Thêm tính năng không sửa code gốc Logging, validation, caching
Advanced Types Kiểm soát kiểu dữ liệu phức tạp API response, Redux state

🤑 Vậy là hôm nay ae ta đã cùng nhau tìm hiểu một vài khái niệm nâng cao của Typescript. Ngoài những thứ trên thì ae sử dụng gì trong dự án của mình.
Hãy comment bên dưới nhé. Bye bye~~

Bình luận

Bài viết tương tự

- vừa được xem lúc

10 Kỹ Thuật Nâng Cao Trong TypeScript Giúp Tối Ưu Mã Nguồn Và Tăng Hiệu Suất

Các Kỹ Thuật Nâng Cao Trong TypeScript. Mình rất vui được chia sẻ những kỹ thuật nâng cao trong TypeScript mà có thể bạn chưa biết đến.

0 0 19

- vừa được xem lúc

Hướng dẫn finetune mô hình LLM đơn giản và miễn phí với Unsloth

Chào mừng các bạn đến với bài viết hướng dẫn chi tiết cách finetune (tinh chỉnh) một mô hình ngôn ngữ lớn (LLM) một cách đơn giản và hoàn toàn miễn phí sử dụng thư viện Unsloth. Trong bài viết này, ch

0 0 2

- vừa được xem lúc

SERIES INDEX NÂNG CAO - BÀI 1: PHÂN TÍCH NHỮNG SAI LẦM PHỔ BIẾN KHI SỬ DỤNG INDEX TRONG MYSQL

Nếu anh em thấy hay thì ủng hộ tôi 1 follow + 1 upvote + 1 bookmark + 1 comment cho bài viết này tại Mayfest 2025 nhé. Còn nếu bài viết chưa hữu ích thì tôi cũng hi vọng anh em để lại những góp ý thẳn

0 0 2

- vừa được xem lúc

"Hack" Não Số Lớn Với Digit DP!

Xin chào anh em, những chiến binh thuật toán kiên cường. Phản ứng đầu tiên của nhiều anh em (có cả tôi): "Ối dào, dễ! Quất cái for từ 1 đến 101810^{18}1018 rồi check thôi!".

0 0 1

- vừa được xem lúc

So Sánh StatelessWidget và StatefulWidget & Các Widget Nâng Cao

Chào mọi người! Hôm nay chúng ta sẽ tiếp tục hành trình khám phá Flutter và đến với bài học về StatelessWidget và StatefulWidget. Trong bài này, mình sẽ giúp các bạn phân biệt sự khác nhau giữa hai lo

0 0 1

- vừa được xem lúc

React Lifecycle & Hooks Cơ Bản

React cung cấp các phương thức lifecycle và hooks để quản lý các giai đoạn khác nhau trong vòng đời của component. Việc hiểu rõ các phương thức này giúp bạn có thể tối ưu hóa ứng dụng React của mình.

0 0 1