Bạn có bao giờ tự hỏi vì sao các chuyên gia TypeScript khuyên không nên dùng Enum? Dù chúng có vẻ hữu ích để định nghĩa các giá trị hằng số, nhưng thực tế, Enum lại mang đến nhiều rủi ro. Trong bài viết này, chúng ta sẽ tìm hiểu lý do tại sao và cách thay thế bằng các giải pháp an toàn hơn.
Enum tạo thêm mã khi biên dịch
Một lý do lớn để không sử dụng Enum là chúng sinh ra mã thừa trong quá trình biên dịch, làm tăng kích thước tệp cuối cùng. Điều này có thể ảnh hưởng tiêu cực đến tốc độ tải và hiệu suất của ứng dụng.
Ví dụ:
enum Roles {
Admin,
Writer,
Reader
}
Mã được sinh ra sau biên dịch:
var Roles;
(function (Roles) {
Roles[Roles["Admin"] = 0] = "Admin";
Roles[Roles["Writer"] = 1] = "Writer";
Roles[Roles["Reader"] = 2] = "Reader";
})(Roles || (Roles = {}));
Mã này làm tệp lớn hơn, đặc biệt khi bạn chia sẻ mã giữa frontend và backend.
String Enum gây khó khăn về tương thích type
Với string Enum, chỉ các giá trị Enum cụ thể mới được chấp nhận, ngay cả khi bạn cung cấp một string hợp lệ.
Ví dụ:
enum Roles {
Admin = 'admin',
Writer = 'writer',
Reader = 'reader'
}
declare function hasAccess(role: Roles): void;
hasAccess('admin'); // Sai.
hasAccess(Roles.Admin); // Đúng.
Điều này làm giảm tính linh hoạt và có thể gây khó khăn khi tích hợp với các hệ thống hoặc thư viện khác.
Giải pháp thay thế Enum
Thay vì Enum, bạn có thể sử dụng object kết hợp với type. Cách tiếp cận này không chỉ an toàn hơn mà còn dễ mở rộng và bảo trì.
Ví dụ với object:
const Roles = {
Admin: 'admin',
Writer: 'writer',
Reader: 'reader'
} as const;
// Tạo type từ object
type RoleKeys = typeof Roles[keyof typeof Roles];
declare function hasAccess(role: RoleKeys): void;
hasAccess('guest'); // Sai.
hasAccess('admin'); // Đúng.
hasAccess(Roles.Admin); // Đúng.
Sử dụng object:
- Tương thích tốt với các hệ thống khác.
- Không sinh mã thừa khi biên dịch.
- Linh hoạt trong việc mở rộng hoặc thay đổi.
Kết luận
Enum trong TypeScript tiềm ẩn nhiều rủi ro về hiệu suất và tính tương thích. Thay vì sử dụng Enum, hãy áp dụng object và type để tạo mã nguồn gọn nhẹ, linh hoạt và an toàn hơn. Một thay đổi nhỏ nhưng sẽ mang lại sự khác biệt lớn trong dự án của bạn!
Tham khảo: https://basarat.gitbook.io/typescript/type-system/enums