Historia pytania: W JavaScript funkcje często używają destrukturyzacji obiektów bezpośrednio w sygnaturze. W TypeScript takie podejście wymaga dokładnego opisania struktury destrukturyzowanych parametrów oraz ustalenia wartości domyślnych — w przeciwnym razie mogą wystąpić błędy podczas próby uzyskania dostępu do nieistniejących właściwości oraz błędne wnioski typów.
Problem: Nieoczywiste jest, jak poprawnie opisać typ całego parametru lub poszczególnych zagnieżdżonych właściwości w destrukturyzowanym obiekcie, szczególnie gdy występują opcjonalne i zagnieżdżone pola, a także wartości domyślne.
Rozwiązanie: Zawsze opisuj osobny typ lub interfejs dla struktury parametrów funkcji, wyraźnie wskazując, które pola są obowiązkowe, które — opcjonalne, a wartości domyślne ustalaj w ciele funkcji lub bezpośrednio w parametrach za pomocą składni ES6.
Przykład kodu:
interface UserOptions { name: string; age?: number; address?: { city: string; zipcode?: string }; } function registerUser( { name, age = 18, address = { city: 'Unknown' } }: UserOptions ): string { return `${name}, ${age}, ${address.city}`; }
Kluczowe cechy:
Czy można pominąć opis typu obiektu-parametru — polegając na automatycznym wnioskowaniu?
Nie, to niebezpieczne. Jeśli nie wskazać typu UserOptions, kompilator nie poda informacji o obowiązkowych właściwościach, wartości domyślne nie będą zgłaszane dla zagnieżdżonych pól, pojawią się niejawne błędy na etapie użycia.
function example({ x, y }) { ... } // x i y — any
Jak ustawić wartość domyślną dla zagnieżdżonego obiektu, częściowo zastępując właściwości?
Użyj spread. Jednak spread nie "łączy" typów, jeśli typ address jest opcjonalny. Należy przeprowadzić sprawdzenie lub jasno ustalić domyślną wartość.
function fn({ obj = { foo: 1 } }: { obj?: { foo: number } }) { const address = { foo: 42, ...obj }; }
Czym grozi destrukturyzacja z opcjonalnymi polami bez domyślnych wartości?
Jeśli pominiesz domyślną wartość dla opcjonalnych właściwości, odwołania do właściwości (na przykład address.city) mogą prowadzić do błędów wykonania. Lepiej jednoznacznie ustalić ? i wartość domyślną.
function danger({ address }: { address?: { city: string } }) { console.log(address.city); // Błąd, address może być undefined }
W starej wersji kodu destrukturyzowano obiekt parametrów bez wyraźnej typizacji. Po dodaniu nowego pola do funkcji wszystkie miejsca użycia nie zostały automatycznie znalezione, co spowodowało błędy na produkcji.
Zalety:
Wady:
Wdrożono interfejsy dla wszystkich takich funkcji, pokryto testami scenariusze z undefined i wartościami domyślnymi, sugestie kompilatora ułatwiły wprowadzanie masowych zmian.
Zalety:
Wady: