TypeScript realizuje mechanizm sprawdzania nadmiarowych właściwości (Excess Property Checking) dla dodatkowego bezpieczeństwa, aby ostrzec programistę o błędach w deklaracjach obiektów, gdy literał obiektu jest bezpośrednio przypisywany do zmiennej z określonym typem. Mechanizm powstał, ponieważ strukturalne typowanie TypeScript może akceptować niejawne, dodatkowe właściwości, co często prowadzi do błędów w logice programu, szczególnie podczas pracy z API lub formularzami.
Sprawdzanie nadmiarowych właściwości zostało wprowadzone w celu poprawy bezpieczeństwa front-endowego programowania, gdzie struktura obiektów często podąża za ścisłym modelem kontraktowym (na przykład w celu serializacji do JSON). Gdy obiekt jest tworzony jako literał i natychmiast przekazywany do funkcji lub zapisywany w zmiennej o określonym typie, TS przeprowadza "naddatnią" kontrolę — szuka dodatkowych właściwości, które nie są opisane w zakładanym typie.
Błąd programisty może pozostać niezauważony, jeśli obiekt zawiera literówkę lub dodatkową właściwość, a taka właściwość nie zostanie użyta prawidłowo lub całkowicie zostanie pominięta przez logikę biznesową. Ponadto, Excess Property Checks mogą zadziałać w sposób nieoczekiwany — na przykład, jeśli obiekt nie jest jawnie typowany lub jest przetwarzany za pomocą operatorów spread lub przez zmienne pośrednie.
TypeScript stosuje Excess Property Checks do literałów obiektowych, które są przypisywane bezpośrednio do zmiennej lub parametru funkcji. Kontrola szuka wszystkich właściwości obiektu i porównuje je z zadeklarowanym typem — jeśli są nadmiarowe, zostanie zgłoszony błąd kompilacji.
interface UserProfile { name: string; age: number; } const user: UserProfile = { name: "Sam", age: 25, email: "sam@mail.com" // Błąd: dodatkowa właściwość email };
Aby obejść nadmiarową kontrolę, na przykład dla obiektów z dynamicznymi właściwościami lub częściowym typowaniem, stosuje się indeksy sygnatury lub zmienne pośrednie.
interface FlexibleUser { name: string; [prop: string]: any; // Indeks sygnatury pozwala na dowolne nowe właściwości } const user2: FlexibleUser = { name: "Sam", age: 25, email: "sam@mail.com" // Działa poprawnie };
Kluczowe cechy:
Czy jeśli stworzysz obiekt z dodatkową właściwością, przypiszesz go do zmiennej bez typu, a potem przypiszesz typ, zadziała Excess Property Checks?
Nie, sprawdzanie nadmiarowe działa tylko przy bezpośrednim przypisaniu literału. Jeśli obiekt stworzono wcześniej, a potem tylko określa się typ, nadmiarowe właściwości nie są wykrywane.
const temp = { name: "John", age: 18, foo: "bar" }; const u: UserProfile = temp; // Brak błędu, foo zignorowane
Czy Excess Property Checks działają dla klas i instancji klas?
Nie, w przypadku klas i instancji klas ta kontrola nie jest wykonywana, tylko dla literałów obiektów.
Czy można globalnie wyłączyć nadmiarowe kontrole w ustawieniach TS?
Nie, nie ma osobnego ustawienia do wyłączenia tego. Można jednak określić indeksy sygnatury dla właściwości lub używać operatora type assertion ('as'), aby wyraźnie wskazać, że kontrola nie jest potrzebna.
const special: UserProfile = { name: "Max", age: 22, hobby: "js" } as UserProfile;
Programista tworzy interfejs dla formularza użytkownika, pozwala na wszystkie właściwości przez [key: string]: any, aby nie występowały błędy przy dodatkowych polach.
Plusy: Nie pojawiają się błędy kompilacji przy dynamicznych danych
Minusy: Jakiekolwiek błędy w strukturze formularza lub literówki nie są wykrywane, trudno jest znaleźć błędy
Programista określa ścisły interfejs i używa osobnej funkcji do transformacji danych dynamicznych do ścisłej struktury, z wstępną walidacją.
Plusy: Interfejs zawsze odpowiada oczekiwanemu kontraktowi, kompilator wyłapuje literówki, wysoka konserwowalność
Minusy: Należy napisać dodatkowy kod do sprawdzania i mapowania danych dynamicznych