PorównaniePorównania

any vs unknown

any wyłącza sprawdzanie typów i pozwala na wszystko, a unknown też przyjmie każdą wartość, ale wymaga sprawdzenia typu, zanim jej użyjesz.

Na tej stronie

Porównanie w tabeli

#
  • Przyjmuje każdą wartość

    any
    Tak
  • Użycie bez sprawdzenia typu

    any
    Tak, kompilator nie protestuje
    unknown
    Nie, trzeba najpierw zawęzić typ
  • Wywołanie dowolnej metody

    any
    Dozwolone, nawet błędnej nazwy
    unknown
    Błąd: Object is of type 'unknown'
  • Przypisanie do innego typu bez sprawdzenia

    any
    Dozwolone
    unknown
    Zablokowane
  • Gdzie błąd wychodzi na jaw

    any
    Dopiero w działającym programie
    unknown
    Już podczas kompilacji
  • Typowe użycie

    any
    Migracja z JavaScriptu, biblioteki bez typów
    unknown
    Dane z API, JSON.parse(), catch (error)

Przykład

#
TypeScript
function describeAny(value: any): string {
  return value.toUpperCase()
}

function describeUnknown(value: unknown): string {
  if (typeof value === 'string') return value.toUpperCase()
  return 'nieznany typ'
}

console.log(describeAny('html'))
console.log(describeUnknown('css'))
console.log(describeUnknown(42))
Wynik
HTML
CSS
nieznany typ

Definicja i zastosowanie

#

Oba typy przyjmują wartość jakiegokolwiek typu: możesz przypisać do zmiennej any albo unknown napis, liczbę, obiekt czy wynik JSON.parse(). W obu przypadkach kompilator nie wie z góry, czym naprawdę jest ta wartość.

Różnica jest w tym, co wolno zrobić dalej. Na wartości any możesz od razu wywołać dowolną metodę i przekazać ją wszędzie, bez żadnego sprawdzenia, bo kompilator przestaje pilnować typów. Na wartości unknown nie zrobisz nic, dopóki nie zawężysz typu przez typeof, instanceof, Array.isArray() albo własny strażnik typu. Dopiero po takim sprawdzeniu kompilator udostępnia metody właściwe dla rozpoznanego typu.

any to furtka, która wyłącza TypeScript tam, gdzie jej użyjesz, i łatwo przez nią przepuścić błąd do działającego programu. unknown daje tę samą elastyczność przy przyjmowaniu danych, ale zmusza do ich sprawdzenia, więc dla danych z zewnątrz (API, JSON.parse(), localStorage) wybieraj unknown. any zostaw jako tymczasowe rozwiązanie przy migracji z JavaScriptu.

Składnia

#
Składnia
let wartosc: any
let inna: unknown

Więcej przykładów

#
any nie chroni przed błędem w działającym programie
TypeScript
const broken: any = { user: null }

try {
  console.log(broken.user.name)
} catch (error) {
  console.log('Błąd w działaniu, kompilator nic nie zgłosił')
}
Wynik
Błąd w działaniu, kompilator nic nie zgłosił
unknown blokuje użycie bez sprawdzenia
TypeScript
const input: unknown = JSON.parse('{"level":7}')
console.log(input.level)
// Błąd: 'input' is of type 'unknown'.

Dobre praktyki

#
  • Włącz opcję noImplicitAny, żeby kompilator nie przyjmował any po cichu tam, gdzie nie podałeś typu.
  • Błąd w catch (error) ma typ unknown. Sprawdź error instanceof Error, zanim odczytasz error.message.
  • Jeśli migrujesz kod z any na unknown, kompilator sam wskaże każde miejsce, które wymaga sprawdzenia typu.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.