programowanieProgramista Frontend

Do czego potrzebne i jak działają const enum w TypeScript? Czym różnią się od zwykłych enum i jakie są pułapki oraz ograniczenia przy ich użyciu?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania:

Enum — typ, który pochodzi z C/C++ i innych języków, do opisu skończonych zestawów nazwanych stałych. W JavaScript ich nie było, ale TypeScript wprowadził wsparcie. W celu zwiększenia wydajności wymyślono const enum — rozszerzenie, w którym wartości są wstawiane bezpośrednio na etapie kompilacji, a nie jako pełnoprawne obiekty.

Problem:

Zwykłe enum generują w JS znaczną ilość pomocniczego kodu (obiekty, które zapewniają dwukierunkowy związek nazwa<->wartość). Nie zawsze jest to potrzebne, szczególnie gdy ważna jest maksymalna wydajność i minimalny rozmiar bundla.

Rozwiązanie:

Używaj const enum, jeśli chcesz inlinować wartości podczas kompilacji i uniknąć dodatkowego kodu. Jednak const enum ma ograniczenia — działa tylko w ramach projektu TypeScript, trudno je używać przy transpilacji do różnych modułów, a także mogą wystąpić problemy z tree shaking i import/export.

Przykład kodu:

const enum Direction { Up, Down, Left, Right } const move = Direction.Left; // W JS zamieni się po prostu na 2

Kluczowe cechy:

  • Wartości są wstawiane bezpośrednio bez generowania obiektu enum.
  • Nie wspierają złożonych wartości ani obliczeń w ciele enum.
  • Nieeksportowalne (najczęściej błędy przy użyciu w bibliotekach lub z isolatedModules).

Pytania z podstępem.

Czy można używać const enum w plikach d.ts i bibliotekach ogólnego użytku?

Nie. Zaleca się unikanie const enum w bibliotekach, ponieważ są one wstawiane tylko podczas kompilacji, co często powoduje błędy przy ponownym kompilowaniu i opisywaniu typów.

Co się stanie, gdy użyjesz const enum z parametrem isolatedModules lub podczas kompilacji z babel?

Pojawi się błąd: babel i isolatedModules nie wspierają inlining const enum, ponieważ nie mogą zapewnić bezpiecznego wstawiania wartości na etapie kompilacji pojedynczego pliku.

Czy można używać obliczonych wartości i wartości stringowych w const enum?

Złożone obliczenia (np. wyrażenia przez funkcje lub zmienne) są zabronione. Można tylko proste liczby i ciągi.

Typowe błędy i antywzorce

  • Używanie const enum w ogólnym API biblioteki lub w plikach .d.ts.
  • Transpilacja bez wsparcia dla inlining const enum (np. przez babel bez specjalnego pluginu).
  • Dodawanie złożonych wyrażeń i wartości stringowych zamiast prostych.

Przykład z życia

Negatywny przypadek

Opublikowano const enum w bibliotece, opisano go w .d.ts, konsument otrzymał błąd z powodu braku ciągu importu w finalnym bundlu.

Zalety:

  • Szybkie wykonanie, brak niepotrzebnego kodu w zależnych projektach.

Wady:

  • Błędy kompilacji i runtime u użytkowników.

Pozytywny przypadek

Użyto const enum tylko wewnątrz prywatnych części projektu, nie eksportując na zewnątrz:

const enum Color { Red, Green, Blue } let arr = [Color.Red, Color.Green];

Zalety:

  • Kompaktowy wyjściowy kod JS.
  • Gwarancja bezpieczeństwa i łatwości w utrzymaniu.

Wady:

  • Nie można eksportować na zewnątrz.