programowanieProgramista Fullstack

Czym jest keyof typeof w TypeScript? Jak działa ich kombinacja i gdzie jest stosowana w praktyce?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Operatory keyof i typeof to potężne narzędzia typizacji w TypeScript. Ich wspólne użycie pozwala na dynamiczne tworzenie typów, tworzenie bezpiecznych funkcji i wyrażanie struktury obiektów w maksymalnie elastyczny sposób.

Historia pytania

typeof w TypeScript służy do wyprowadzania typu na podstawie zmiennej, a keyof zwraca unię wszystkich kluczy obiektu lub typu. W zestawieniu pozwalają one pracować z dynamicznie zadeklarowanymi obiektami i tworzyć typy wzajemnie powiązane.

Problem

Bez tych operatorów, podczas pracy z obiektami, enumami i tabelami zgodności często trzeba ręcznie powtarzać ciągi kluczy w typach i wartościach, co prowadzi do błędów niespójności i utrudnia utrzymanie kodu.

Rozwiązanie

Za pomocą typeof uzyskujemy typ z wartości zmiennej, a za pomocą keyof tworzymy typ unii wszystkich jej kluczy. Efekt — automatyzacja typizacji.

Przykład kodu:

const ERRORS = { NOT_FOUND: 'Not found', UNAUTHORIZED: 'Unauthorized', SERVER_ERROR: 'Server error', }; // Za pomocą typeof uzyskujemy typ, a za pomocą keyof — wszystkie klucze obiektu function getErrorMessage(code: keyof typeof ERRORS): string { return ERRORS[code]; }

Kluczowe cechy:

  • Pomaga w budowaniu ściśle powiązanych typów klucz-wartość bez ręcznego aktualizowania.
  • Pozwala na typizację funkcji, które pracują z kluczami obiektów.
  • Eliminacja problemów z niespójnością między kluczami a typami.

Pytania z zawiązaniem.

Czy wartości obiektu uzyskane za pomocą typeof mogą automatycznie stać się kluczami w typie unii?

Nie, typeof zwraca typ struktury obiektu, a nie wartości. Aby uzyskać unię wartości, należy osobno uzyskać typy wartości.

Co zwróci typeof dla enumu i co zwróci keyof typeof dla enumu?

Dla enumu typeof zwraca typ obiektu enum (w obu kierunkach: klucz-wartość i wartość-klucz), podczas gdy keyof typeof zwraca unię kluczy stringowych/liczbowych tego obiektu. Na przykład:

enum Colors { Red = 'R', Blue = 'B' } type ColorKeys = keyof typeof Colors; // 'Red' | 'Blue'

Czy za pomocą keyof typeof można uzyskać bezpieczną typowo listę wszystkich możliwych parametrów funkcji, która przyjmuje klucze obiektu?

Tak, w ten sposób tworzysz funkcję, która przyjmuje tylko dozwolone klucze. To zapobiega błędom podczas pracy z kluczami obiektów.

const config = { mode: 'dark', lang: 'ru' }; type ConfigKeys = keyof typeof config; // 'mode' | 'lang' function useConfig(key: ConfigKeys) { // ... }

Typowe błędy i antywzorce

  • Błędne oczekiwanie, że keyof typeof jest stosowane do wartości tablic — dla tablic są to indeksy, a nie wartości.
  • Niezrozumienie, że typeof działa na poziomie typów, a nie zwraca wartości w czasie działania.
  • Stosowanie wobec typu, który nie jest jawnie zadeklarowany, co psuje wyprowadzanie typów.

Przykład z życia

Przykład negatywny

W stałej z kodami statusów API ręcznie przepisują typy stringowych kluczy:

type StatusCodes = 'OK' | 'FAIL' | 'PENDING'; function isKnownStatus(code: StatusCodes) { /* ... */ }

Zalety:

  • Jasno widać, jakie ciągi są dozwolone.

Wady:

  • Konieczność ręcznej zmiany typów przy aktualizacji listy; niespójność i błędy.

Przykład pozytywny

Użycie keyof typeof dla automatycznego wsparcia listy:

const STATUS = { OK: 1, FAIL: 0, PENDING: 2 }; type StatusKeys = keyof typeof STATUS; function checkStatus(key: StatusKeys) { /* ... */ }

Zalety:

  • Przy dodawaniu/usuwaniu statusu typ automatycznie się zaktualizuje.
  • Brak niespójności typów i wartości.

Wady:

  • Praca z bardzo złożonymi strukturami wymaga doświadczenia i uwagi.