TypeScript: Don’t Export const enums

2 min read

Nếu bạn đang viết một thư viện và bạn export 1 const enum, một số dev sẽ không thể biên dịch ứng dụng của họ nếu họ import thư viện của bạn. Hãy xem tại sao

Non-const enums

Khi bạn khai báo một enum, TypeScript sẽ generate code cho nó.

enum Color{
  Red,
  Green,
  Blue
}
let value = Color.Blue;

sẽ được biên dịch thành JS như này:

var Color;
(function (Color) {
  Color[(Color["Red"] = 0)] = "Red";
  Color[(Color["Green"] = 1)] = "Green";
  Color[(Color["Blue"] = 2)] = "Blue";
})(Color|| (Color= {}));
let value = Color.Blue;

Tuy nhiên một số dev sẽ không thích kiểu khai báo này, họ chỉ muốn sử dụng enum thay vì hằng số

const enums

Khi khai báo enum với const, Typescript sẽ không generate code.

enum Color{
  Red,
  Green,
  Blue
}
let value = Color.Blue;

sẽ được biên dịch thành JS như này:

let value = 2; /* Blue*/

Không có code nào được sinh ra cho khai báo enum, nó giống như việc sử dụng một hằng số — nhưng có một vấn đề.

Isolated modules

Ở ví dụ phía trên, Typescript có thể truy cập được khai báo của const enum qua let value = Color.Blue; là vì cả hai đang ở cùng một module

Tuy nhiên, nếu ta khai báo enum Color ở một module khác và import nó vào một module khác để sử dụng, Typescript sẽ phải đọc ở cả hai module để có thể xác định được giá trị của Color.Blue là 2

Đây chính là vấn đề, bởi vì một số dev sẽ tách biệt quá trình kiểm tra type ra khỏi quá trình biên dịch – quá trình biên dịch sẽ diễn ra trong một module cô lập:

  • Trình biên dịch sẽ đọc một Typescript module
  • Thông tin về type module sẽ được bỏ qua
  • Những gì còn lại là module JavaScript mà trình biên dịch viết

Quá trình biên dịch này sẽ không đọc những module được import từ ngoài vào, vì thế nó sẽ không thể hỗ trợ việc thay đổi giá trị cho const enum như Color.Blue

Hàm transpileModule trong API của trình biên dịch Typescript sẽ thực hiện kiểu biên dịch như trên, cũng như với @babel/plugin-transform-typescript được sử dụng trong create-react-app

Typescript có một tùy chọn biên dịch là isolatedModulesđể kiểm tra bổ sung nhằm đảm bảo code được biên dịch là an toàn cho loại quy trình biên dịch kiểu như trên. Nếu bạn đang viết một thư viện, bạn nên sử dụng loại tùy chọn này để đảm bảo bạn sẽ không export các const enum và các dev khác khi sử dụng Typescript sẽ có thể biên dịch thư viện của bạn khi import vào

Tham khảo thêm tại đây https://www.typescriptlang.org/docs/handbook/enums.html#const-enums

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *