Typ Record w TypeScript wyjaśniony na Twoich własnych kluczach
Typ Record w TypeScript
TypeScript Record<K, V>: typowane obiekty słownikowe wyjaśnione | We.Inc
Zbuduj typ Record<K, V> z własnych kluczy i zobacz obiekt, który opisuje. Dowiedz się, kiedy Record wygrywa z index signature lub Map i jakie błędy wyłapuje.
Record<K, V> to wbudowany typ narzędziowy dla obiektu, którego klucze pochodzą z K, a wszystkie wartości mają typ V. Podaj mu unię literałów string, a kompilator wymusi obecność każdego wymienionego klucza. Podaj zwykły string, a zachowa się jak otwarty słownik, tak samo jak index signature.
Record w skrócie
Piszesz
Oznacza
Czy klucz może brakować?
Record<"a" | "b", number>
{ a: number; b: number }
Nie, oba klucze wymagane
Record<string, number>
{ [key: string]: number }
Tak, dowolny klucz string
Partial<Record<"a" | "b", number>>
{ a?: number; b?: number }
Tak, każdy klucz opcjonalny
Record<number, string>
{ [key: number]: string }
Tak, dowolny klucz number
Wpisz potrzebne klucze i wybierz typ wartości. Kreator zapisuje typ Record, zwykły typ obiektowy, do którego się rozwija, oraz obiekt startowy z jedną linią na klucz, abyś przed wklejeniem do kodu zobaczył dokładnie, czego będzie od Ciebie wymagał kompilator.
Wpisz klucze oddzielone przecinkami, na przykład home, about, contact.
Wybierz typ wartości, który ma przechowywać każdy klucz.
Zaznacz opcję opcjonalności, jeśli niektóre klucze mogą zostać pominięte, co opakowuje typ w Partial.
Skopiuj typ i obiekt startowy do swojego pliku i uzupełnij wartości.
Wyprowadzaj unię kluczy z danych, które już masz: keyof typeof someObject albo (typeof list)[number] po tablicy z as const utrzymuje Record w zgodzie ze źródłem.
Sięgaj po Record<string, T> tylko wtedy, gdy klucze naprawdę przychodzą w czasie działania programu. Zamknięta unia wyłapuje literówki w nazwach właściwości, które otwarty słownik przepuszcza.
Włącz noUncheckedIndexedAccess, jeśli odczytujesz z Record<string, T> po wyliczonym kluczu. Odczyty zwracają wtedy T | undefined, co odpowiada temu, co dzieje się w runtime.
Unikaj Record<string, any>. Record<string, unknown> nadal przyjmuje dowolny obiekt, ale wymusza sprawdzenie przed użyciem wartości.
Najczęściej zadawane pytania
Czy Record to to samo co index signature?
Przy szerokim kluczu, takim jak string, tak: Record<string, number> i { [key: string]: number } opisują ten sam kształt. Różnicę widać przy kluczach literałowych. Index signature nie może wymagać istnienia konkretnych nazw, a Record<"a" | "b", number> wymaga zarówno a, jak i b.
Kiedy użyć Map zamiast Record?
Używaj Map, gdy klucze są często dodawane i usuwane, gdy klucze nie są stringami albo gdy potrzebujesz liczby wpisów przez size. Używaj Record dla stałego zestawu nazw, obiektów konfiguracyjnych i wszystkiego, co przepuszczasz przez JSON.stringify.
Dlaczego TypeScript mówi, że w moim Record brakuje właściwości?
Bo typ klucza jest unią, a obiekt pomija jeden z jej elementów. tsc zgłasza na przykład Property 'about' is missing in type '{ home: string; }'. Dodaj klucz albo opakuj typ w Partial, jeśli jego pominięcie jest poprawne.
Czy Record istnieje w runtime?
Nie. To wyłącznie typ i znika po kompilacji kodu. Obiekt, który tworzysz, to zwykły obiekt JavaScript, więc kompilator nie powstrzyma odpowiedzi serwera przed nadmiarowymi lub brakującymi kluczami.
W której wersji TypeScript dodano Record?
Record pojawił się w TypeScript 2.1, razem z Partial, Readonly i Pick, więc ma go każdy aktualny kompilator.
Jak zbudowany jest Record
Record to mapped type. Przechodzi przez każdy element typu klucza i nadaje każdemu ten sam typ wartości, dlatego Record<"a" | "b", number> rozwija się do typu obiektowego z dwiema wymaganymi właściwościami typu number.
Ponieważ to tylko typ, możesz mu podać wszystko, co może być kluczem właściwości: literały string, number, string, symbol lub unię tych typów. Typ klucza zbudowany z innego typu, na przykład keyof User, aktualizuje się sam, gdy zmienia się User.
Klucze zamknięte kontra klucze otwarte
Wartość Record tkwi w formie zamkniętej. Tablica przeglądowa nazw tras, etykiet statusów czy kolorów motywu typowana unią literałów psuje build w dniu, gdy ktoś doda nowy status bez etykiety, czyli dokładnie wtedy, gdy chcesz się o tym dowiedzieć.
Forma otwarta, Record<string, T>, opisuje słownik. Nie mówi nic o tym, które klucze istnieją, więc odczyt klucza daje T nawet wtedy, gdy klucza nie ma. Połącz ją z noUncheckedIndexedAccess albo z Map, gdy ta luka ma znaczenie.
Record, index signature czy Map
Wybierz Record z kluczami literałowymi dla stałych tablic przeglądowych, Record<string, T> lub index signature dla słowników w kształcie JSON, a Map dla kolekcji zmieniających się w trakcie działania programu. Poradnik o Map w TypeScript na tej stronie szczegółowo omawia ten ostatni przypadek.
Wzorce, których użyjesz najczęściej
Klucze z tablicy as const
Tablica jest jedynym źródłem prawdy. Dodaj do niej status, a kompilator będzie wskazywał tabelę etykiet, dopóki nie dodasz też etykiety.
Jedna flaga na każde pole innego typu
keyof zamienia istniejący typ w unię kluczy, więc obiekt stanu touched formularza zawsze wymienia te same pola co formularz.
Otwarty słownik, bezpieczny odczyt
Przy włączonym noUncheckedIndexedAccess odczyt po wyliczonym kluczu ma typ number | undefined, więc wartość zastępcza jest wymagana, a nie zapominana.
Kreator typu Record
Klucze oddzielone przecinkami
Typ wartości
Klucze są opcjonalne (opakuj w Partial)
Typ
Do czego się rozwija
Obiekt startowy
Wpisz co najmniej jeden klucz. Klucze muszą zaczynać się od litery, _ lub $.