Functions và Object Types trong TypeScript

Functions và Object Types trong TypeScript

26 June, 2025

Module 3 - Functions và Object Types 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 hành trình làm chủ TypeScript, việc hiểu sâu về cách hoạt động của hàm và các kiểu đối tượng là vô cùng quan trọng. Tiếp nối loạt bài "Dựng khung dự án", hôm nay tôi muốn chia sẻ những kiến thức cốt lõi từ Module 3 về Functions và Object Types trong TypeScript. Đây không chỉ là những khái niệm cơ bản mà còn là chìa khóa để chúng ta xây dựng các ứng dụng mạnh mẽ và dễ bảo trì.

1. Định Nghĩa Kiểu Hàm (Function Type Expressions)

TypeScript cho phép chúng ta định nghĩa kiểu tường minh cho hàm, giúp tăng cường tính an toàn và dễ đọc.

  • Cú pháp cơ bản: (tên_tham_số: Kiểu) => Kiểu_trả_về
  • Ví dụ: let greetFunction: (name: string) => void định nghĩa một hàm nhận vào một string và không trả về giá trị nào.
  • Hàm không trả về (void): Nếu một hàm không trả về giá trị cụ thể, bạn nên dùng void. Lưu ý, void khác undefined (hàm không trả về gì cả) và null (không trả về một giá trị nào đó).

2. Chữ Ký Hàm (Call Signatures)

Chữ ký hàm định nghĩa kiểu cho một hàm trong TypeScript, bao gồm các tham số và kiểu trả về. Nó cho phép chúng ta tái sử dụng cùng một định nghĩa kiểu cho nhiều hàm khác nhau có cùng hành vi.

Ví dụ

Với chữ ký hàm, chúng ta có thể định nghĩa một hàm có thuộc tính mô tả và sau đó triển khai logic cho hành vi của nó.

3. Hàm Khởi Tạo (Construct Signatures)

Trong JavaScript, các hàm khởi tạo (constructor functions) thường được gọi bằng từ khóa new để tạo ra một đối tượng mới. TypeScript mở rộng khái niệm này, cho phép chúng ta định nghĩa kiểu cho các hàm khởi tạo.

  • Cú pháp: new (tên_tham_số: Kiểu) => Kiểu_đối_tượng

Ví dụ

Chỉ những hàm khởi tạo được định nghĩa rõ ràng với new mới có thể dùng từ khóa new khi tạo đối tượng. Điều này giúp tăng tính minh bạch và an toàn trong code.

4. Hàm Generic (Generic Functions)

Generic functions cho phép chúng ta viết các hàm linh hoạt, có thể hoạt động với nhiều kiểu dữ liệu khác nhau mà vẫn giữ được tính an toàn kiểu.

  • Cú pháp: function identity<T>(arg: T): T { return arg }
  • Ví dụ: function firstElement<Type>(arr: Type[]): Type | undefined { ... }

Hàm firstElement nhận vào một mảng bất kỳ kiểu Type và trả về phần tử đầu tiên của mảng đó, hoặc undefined nếu mảng rỗng. Điều này giúp tái sử dụng code mà không cần viết lại cho từng kiểu dữ liệu cụ thể.

5. Một Số Kiểu Hàm Khác

  • void: Đại diện cho hàm không trả về giá trị nào. void khác undefinednull.
  • object: Kiểu object là kiểu đặc biệt cho bất kỳ giá trị nào không phải kiểu nguyên thủy (string, number, boolean, symbol, null, undefined). Nó khác với {} (đối tượng rỗng).
  • unknown: Giá trị unknown đại diện cho any nhưng an toàn hơn. Khi sử dụng unknown, bạn phải thực hiện kiểm tra kiểu (type narrowing) trước khi có thể tương tác với giá trị đó.
  • never: Đại diện cho hàm không bao giờ trả về dữ liệu (ví dụ: hàm ném lỗi, hàm vòng lặp vô hạn).
  • Function: Mô tả tất cả các thuộc tính phổ biến của các hàm trong JavaScript (như bind, call, apply).

6. Kiểu Đối Tượng (Object Types)

Ngoài việc định nghĩa kiểu hàm, TypeScript còn cung cấp các cách mạnh mẽ để định nghĩa cấu trúc của các đối tượng, giúp code minh bạch và dễ quản lý.

  • Khai báo interfacetype alias: Đây là hai cách phổ biến nhất để định nghĩa kiểu đối tượng.
    • Interface: Thường dùng cho các đối tượng có cấu trúc phức tạp và cần khả năng kế thừa.
    • Type Alias: Linh hoạt hơn, có thể dùng để tạo kiểu cho bất kỳ kiểu dữ liệu nào (bao gồm cả kiểu nguyên thủy và union types).
  • readonly properties: Đánh dấu một thuộc tính là chỉ đọc, không thể thay đổi sau khi khởi tạo.
  • Extending Types (Kế thừa kiểu): Interface có thể kế thừa các interface khác, giúp tái sử dụng định nghĩa kiểu và xây dựng các cấu trúc phức tạp một cách có tổ chức.
  • Intersection Types (Kiểu giao nhau): Cho phép kết hợp nhiều kiểu đối tượng thành một kiểu mới, bao gồm tất cả các thuộc tính từ các kiểu đã kết hợp.

Kết Luận:

Việc làm chủ các khái niệm về hàm và kiểu đối tượng trong TypeScript là vô cùng quan trọng để xây dựng các ứng dụng chất lượng cao. Định nghĩa rõ ràng các kiểu dữ liệu không chỉ giúp bạn tránh lỗi mà còn cải thiện khả năng đọc hiểu code, hỗ trợ làm việc nhóm và tăng cường khả năng bảo trì của dự án.

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.

Hy vọng những kiến thức chia sẻ trong bài viết này sẽ giúp ích cho hành trình phát triển của bạn. 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ề một số kiểu dữ liệu đặc biệt và các trường hợp sử dụng nâng cao trong TypeScript.
Chúc các bạn học tập và làm việc hiệu quả!