TypeScript wspiera precyzyjne typowanie funkcji z użyciem parametrów rest oraz destrukturyzacji. Jest to szczególnie ważne dla funkcji przyjmujących zmienną liczbę argumentów lub złożone obiekty.
Destrukturyzacja w parametrach funkcji pozwala wyraźnie określić strukturę oczekiwanych właściwości:
function printUser({ name, age }: { name: string; age: number }) { console.log(`${name} (${age})`); }
Parametry rest pozwalają określić zmienną liczbę argumentów i ich typ:
function sum(...numbers: number[]): number { return numbers.reduce((acc, cur) => acc + cur, 0); }
Połączenie tych rozwiązań występuje w funkcjach, które przyjmują główny obiekt oraz dodatkową tablicę parametrów:
function logEvent(event: { type: string }, ...meta: any[]) { console.log(event.type, meta.join(',')); }
Poprawne typowanie pozwala wychwycić błędy przed wykonaniem kodu, ale niewłaściwe typowanie prowadzi do utraty bezpieczeństwa typów oraz błędów w czasie wykonywania.
Jak określić typ dla funkcji z domyślnie destrukturyzowanymi parametrami i uczynić je opcjonalnymi?
Wielu podaje typ obiektu, ale zapomina uczynić każde pole opcjonalnym lub ustawić wartości domyślne jednocześnie z typem:
function foo({x = 1, y = 2}: {x?: number; y?: number} = {}) { console.log(x, y); }
Tutaj wartości domyślne są określone, a wszystkie parametry są czynione opcjonalnymi za pomocą ?. Bez tego wywołanie bez parametrów spowoduje błąd, mimo iż oczekiwany jest domyślny.
Historia
undefined nie ma właściwości name.Historia
any[], co umożliwiło przekazanie nie tylko liczb. Na produkcji niespodziewanie zsumowano liczby i napisy, uzyskując nieprawidłowe wyniki w raportach.Historia
Użyto destrukturyzacji z głęboko zagnieżdżonym obiektem, ale nie określono zagnieżdżonych typów. Z tego powodu TS "zgubił się" i nie podpowiedział o braku obowiązkowego pola w obiektach, co doprowadziło do błędu TypeError: Cannot read property 'id' of undefined po stronie klienta.