programowanieFrontend deweloper

Wyjaśnij, jak działa operator guard typeof w TypeScript, jak i do czego się go używa oraz jakie ma ograniczenia?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania

W JavaScript operator typeof jest używany do sprawdzania typu prymitywnych wartości w czasie wykonywania. TypeScript rozszerza ten mechanizm i czyni go częścią systemu zwężania typów (type narrowing) poprzez typowe gardy (type guards). TypeScript wykorzystuje wynik operatora typeof do precyzowania typu zmiennej wewnątrz bloku kodu, co pozwala dokładniej opisać logikę działania funkcji, szczególnie podczas pracy z typami unii.

Problem

W standardowym JavaScript po sprawdzeniu typu wartości za pomocą typeof nie ma żadnej gwarancji typowej — programista musi pamiętać, co dzieje się w danym fragmencie kodu. Jednak w TypeScript zadanie staje się trudniejsze z powodu różnych typów i typów unijnych, a bez odpowiedniego zwężania typów łatwo popełnić błąd, na przykład próbując uzyskać dostęp do nieistniejącej metody. Operator ma również konkretne ograniczenia: "widzi" tylko podstawowe typy prymitywne, na przykład dla tablic i obiektów zwróci 'object'.

Rozwiązanie

TypeScript pozwala na łączenie operatora typeof z własną analizą typów w celu zwężenia typu zmiennej wewnątrz bloku kodu. To automatycznie zwiększa bezpieczeństwo — kompilator wie, z jakim typem działa kod i podpowiada możliwe właściwości i metody.

Przykład kodu:

function printId(id: number | string) { if (typeof id === 'string') { // W tej gałęzi id: string console.log(id.toUpperCase()); } else { // W tej gałęzi id: number console.log(id.toFixed(2)); } }

Kluczowe cechy:

  • Działa tylko z prymitywami: 'string', 'number', 'boolean', 'symbol', 'undefined', 'object', 'function', 'bigint'.
  • Pomaga TypeScript zwęzić typ unijny do konkretnego prymitywu wewnątrz bloku kodu.
  • Nie różnicuje tablic i obiektów, zawsze zwraca 'object' dla nich.

Pytania z pułapką.

Czy operator typeof może określić tablicę?

Nie, typeof dla tablicy i obiektu zwróci tę samą wartość — 'object'. Aby wyróżnić tablice, lepiej użyć metody Array.isArray().

Przykład kodu:

const arr = [1, 2, 3]; console.log(typeof arr); // 'object' console.log(Array.isArray(arr)); // true

Czy za pomocą typeof można odróżnić null od obiektu?

Nie, typeof null zwraca 'object', to historyczna cecha JavaScript.

Przykład kodu:

console.log(typeof null); // 'object'

Czy za pomocą typeof można sprawdzić klasę użytkownika?

Nie, dla instancji klas typeof również zwróci 'object'. Do tego używa się operatora instanceof lub użytkowych funkcji guard typów.

Przykład kodu:

class User {} const u = new User(); console.log(typeof u); // 'object' console.log(u instanceof User); // true

Typowe błędy i antywzorce

  • Użycie typeof do sprawdzania złożonych struktur danych (na przykład tablic, null, obiektów).
  • Lekceważenie używania operatorów instanceof i Array.isArray() do dokładniejszego zwężania typu.
  • Sprawdzanie typów wyłącznie na poziomie czasu wykonywania, ignorując statyczne sprawdzanie.

Przykład z życia

Negatywny przypadek

Programista napisał funkcję, w której chciał sprawdzić, czy value jest tablicą, używając typeof, i na podstawie wyniku wywoływał różne metody.

Plusy:

  • Łatwy do napisania kod.
  • Nie wymaga dodatkowych funkcji.

Minusy:

  • Funkcja łamie się przy przekazywaniu tablicy: tablica jest postrzegana jako obiekt, błędy w czasie wykonywania.

Pozytywny przypadek

Użycie Array.isArray i połączenie z guard typów.

Plusy:

  • Bezpieczne statyczne typowanie.
  • Brak błędów z typami obiektów vs tablic.

Minusy:

  • Trzeba pamiętać o różnych narzędziach guard typów.