programowanieFrontend developer

Jak działa typizacja stałych obiektów z właściwością as const? Jakie są zalety i jakie problemy mogą wystąpić przy niewłaściwej typizacji takich obiektów?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

as const w TypeScript przekształca wartości i właściwości obiektu/tablicy w readonly i typy literałowe. Daje to ścisłą typizację: wartości nie są "rozszerzane" do typów podstawowych, ale zachowują swoją konkretną wartość.

Przykład:

const a = { status: 'success' }; // Typ: { status: string } const b = { status: 'success' } as const; // Typ: { readonly status: "success" }

Zalety:

  • Ścisła typizacja (np. switch/case po stringach, listy stałych)
  • Idealne dla enums, actionTypes w Reduxie, list ról itp.
  • Zapobiega przypadkowemu zmianie wartości

Wady/Cechy:

  • Właściwości stają się readonly, próba ich zmiany wywoła błąd.
  • Nieuwaga może prowadzić do niespójności typów (np. jeśli potrzebny jest string, a przesyłany jest literał).

Pytanie z podstępem

Pytanie: Jeśli użyć as const dla tablicy z stringami, jaki będzie jej typ, i czy można będzie ją przekazać jako zwykły string[]?

Odpowiedź: Typ będzie readonly ["a", "b", "c"], czyli krotka z typów literałowych z ograniczeniem readonly. Taka tablica jest niekompatybilna z typem string[]; nie można jej bezpośrednio przekazać tam, gdzie oczekiwany jest zmienny tablica stringów.

const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // Błąd! Typ niekompatybilny

Przykłady rzeczywistych błędów z powodu braku znajomości niuansów tematu


Historia

Projekt: Mieliśmy listę actionTypes jako stałą tablicę z as const, a następnie próbowaliśmy ją przekazać do funkcji oczekującej string[]. Otrzymaliśmy błąd typów, musieliśmy jawnie przekształcić za pomocą .slice() lub [...arr].


Historia

Projekt: W mikroframeworku Redux typ action.type definiowaliśmy jako literał przez as const. Podczas implementacji switch-case zapomniano o ścisłej typizacji, nie obsłużono wszystkich możliwych literałów, przez co nie zadziałała kontrola wyczerpania — błąd nie objawił się, aż nie dodano nowego akcji.


Historia

Projekt: Przy auto-generacji końcówek API opisywaliśmy ich klucze przez as const-tablicę. Próba użycia tych kluczy jako indeks zwykłego Record<string, ...> zakończyła się niepowodzeniem z powodu niespójności typów — trzeba było dodać konwersję lub jawnie używać typów kluczy z tablicy.