Enum
Kiểu Enum (liệt kê) được sử dụng trong các trường hợp giá trị bị giới hạn trong một phạm vi nhất định, chẳng hạn như chỉ có bảy ngày trong một tuần, màu sắc được giới hạn là đỏ, xanh lá cây, xanh dương, v.v.
Ví dụ đơn giản
Enum được định nghĩa bằng từ khóa enum
:
Các thành viên của Enum sẽ được gán giá trị từ 0
và tăng lên theo thứ tự, đồng thời cũng sẽ ánh xạ ngược từ giá trị Enum đến tên Enum:
Thực tế, ví dụ trên sẽ được biên dịch thành:
Gán giá trị thủ công
Chúng ta cũng có thể gán giá trị cho các mục enum một cách thủ công:
Trong ví dụ trên, các mục enum mà không được gán giá trị thủ công sẽ tăng theo mục enum trước đó.
Nếu các mục enum không được gán giá trị thủ công trùng với các mục đã được gán giá trị, TypeScript sẽ không nhận biết được điều này:
Trong ví dụ trên, khi tăng lên 3
, nó trùng với giá trị của Sun
đã được gán trước đó, nhưng TypeScript không báo lỗi, dẫn đến giá trị của Days[3]
ban đầu là "Sun"
, nhưng sau đó lại bị "Wed"
ghi đè. Kết quả biên dịch là:
Vì vậy khi sử dụng, bạn cần chú ý, tốt nhất là không nên để xảy ra tình huống ghi đè như vậy.
Các mục enum được gán giá trị thủ công có thể không phải là số, trong trường hợp này cần sử dụng type assertion để cho phép tsc bỏ qua kiểm tra kiểu (js biên dịch vẫn có thể sử dụng):
Dĩ nhiên, các mục enum được gán giá trị thủ công cũng có thể là số thập phân hoặc số âm, trong trường hợp này bước tăng của các mục sau đó không được gán giá trị vẫn là 1
:
Các mục hằng số và mục tính toán
Các mục của enum có hai loại: mục hằng số (constant member) và mục tính toán (computed member).
Các ví dụ trước đây mà chúng ta đã nêu đều là mục hằng số, một ví dụ điển hình về mục tính toán là:
Trong ví dụ trên, "blue".length
là một mục tính toán.
Ví dụ trên sẽ không báo lỗi, nhưng nếu một mục không được gán giá trị thủ công nằm ngay sau một mục tính toán, nó sẽ báo lỗi do không thể lấy giá trị khởi tạo:
Dưới đây là định nghĩa đầy đủ của các mục hằng số và mục tính toán:
Một mục của enum được coi là hằng số khi đáp ứng các điều kiện sau:
- Không có hàm khởi tạo và mục enum trước đó là hằng số. Trong trường hợp này, giá trị của mục enum hiện tại là giá trị của mục enum trước đó cộng thêm
1
. Tuy nhiên, mục đầu tiên của enum là một ngoại lệ. Nếu nó không có hàm khởi tạo, thì giá trị khởi tạo của nó sẽ là0
. - Mục enum được khởi tạo bằng biểu thức enum hằng số. Biểu thức enum hằng số là một tập con của biểu thức TypeScript, nó có thể được tính toán ở giai đoạn biên dịch. Khi một biểu thức đáp ứng một trong các điều kiện sau, nó sẽ là một biểu thức enum hằng số:
- Literal số
- Tham chiếu đến mục enum hằng số được định nghĩa trước đó (có thể được định nghĩa trong các loại enum khác nhau) Nếu mục này được định nghĩa trong cùng một loại enum, bạn có thể sử dụng tên không quy định để tham chiếu
- Biểu thức enum hằng số có dấu ngoặc
+
,-
,~
các toán tử một ngôi áp dụng cho biểu thức enum hằng số+
,-
,*
,/
,%
,<<
,>>
,>>>
,&
,|
,^
các toán tử hai ngôi, biểu thức enum hằng số là một trong các toán hạng của nó. Nếu biểu thức enum hằng số được đánh giá là NaN hoặc Infinity, nó sẽ báo lỗi ở giai đoạn biên dịch
Tất cả các trường hợp khác của mục enum được coi là cần phải được tính toán để lấy giá trị.
Enum hằng số
Enum hằng số là loại enum được định nghĩa bằng const enum
:
Sự khác biệt giữa enum hằng số và enum thông thường là enum hằng số sẽ bị xóa trong quá trình biên dịch, và không thể chứa các mục tính toán.
Kết quả biên dịch của ví dụ trên là:
Nếu chứa các mục tính toán, nó sẽ báo lỗi trong quá trình biên dịch:
Enum bên ngoài
Enum bên ngoài (Ambient Enums) là loại enum được định nghĩa bằng declare enum
:
Như đã đề cập trước đó, loại định nghĩa declare
chỉ được sử dụng cho kiểm tra trong quá trình biên dịch, kết quả biên dịch sẽ bị xóa.
Kết quả biên dịch của ví dụ trên là:
Enum bên ngoài giống như các câu lệnh khai báo, thường xuất hiện trong các tệp khai báo.
Cũng có thể sử dụng declare
và const
cùng một lúc:
Kết quả biên dịch:
Khái niệm về loại enum của TypeScript có nguồn gốc từ C#.