programowanieProgramista Fullstack

Jak zaimplementować i poprawnie typować funkcję zwrotną (callback) z parametrami, które mogą być opcjonalne lub mieć wartości domyślne? Jakie trudności mogą się pojawić i jak ich uniknąć?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania:

Funkcje zwrotne — to powszechna praktyka w JS i TS do programowania asynchronicznego i delegowania odpowiedzialności. W TypeScript typowanie takich funkcji jest ważną częścią zapewnienia bezpieczeństwa, zwłaszcza jeśli parametry mogą być opcjonalne lub mieć wartości domyślne.

Problem:

W dynamicznym JS brak typowania argumentów callback prowadzi do błędów w przekazywaniu wartości, zamieszania z undefined i niewłaściwego porządku parametrów. W TypeScript typowanie jest wymagane, aby uniknąć podobnych problemów, ale na zewnątrz trudno jest uwzględnić wszystkie niuanse związane z opcjonalnością, porządkiem i wartościami domyślnymi.

Rozwiązanie:

Wyraźnie określać typy wszystkich parametrów, opcjonalne parametry oznaczać znakiem zapytania, a wartości domyślne – podawać bezpośrednio przy deklaracji funkcji, pamiętając o poprawnym opisywaniu ich w typie.

Przykład kodu:

function fetchData( url: string, callback: (data: any, error?: Error) => void ) { // ... } // Callback z opcjonalnym parametrem error fetchData('/api', (data, error) => { if (error) { // obsługa } else { // sukces } }); // Callback z parametrem domyślnym function process( cb: (x: number, y?: number) => void = (x, y = 10) => { /* ... */ } ) { /* ... */ }

Główne cechy:

  • Dla parametrów opcjonalnych używany jest znak "?".
  • Dla wartości domyślnych podawana jest wartość domyślna w definicji funkcji.
  • Typowanie ułatwia utrzymanie kodu i zmniejsza liczbę błędów.

Pytania z pułapką.

Czy konsument callbacka musi wyraźnie uwzględniać wszystkie parametry, w tym opcjonalne?

Nie, może pominąć opcjonalne parametry, a TypeScript nie zgłosi błędu — obsługa odbywa się prawidłowo dzięki składni znaku zapytania.

Czy można uczynić pierwszy parametr w callbacku opcjonalnym, a drugi — obowiązkowym?

Nie. Parametry opcjonalne zawsze muszą być na końcu listy argumentów. Naruszenie porządku spowoduje błąd typowania.

Co się stanie, jeśli nie oznaczymy opcjonalności parametru, ale nie przekażemy go w miejscu wywołania?

TypeScript zgłosi błąd — jeśli parametr jest obowiązkowy, musi być przekazany. Tylko opcjonalne lub te z domyślną wartością mogą być pominięte.

Typowe błędy i antywzorce

  • Naruszenie kolejności parametrów opcjonalnych i obowiązkowych (najpierw obowiązkowe, potem — opcjonalne).
  • Brak wyraźnego określenia typów lub użycie "any" — prowadzi do utraty zalet TypeScript.
  • Próby przekazywania undefined zamiast wartości i oczekiwanie na wywołanie wartości domyślnej (uruchamia się tylko w przypadku braku argumentu).

Przykład z życia

Negatywny przypadek

Oznaczyliśmy drugi argument callbacka jako obowiązkowy, a w wywołaniu go nie przekazaliśmy. Otrzymaliśmy błąd kompilacji.

Zalety:

  • Szybko i łatwo napisany kod bez doprecyzowań.

Wady:

  • Nie kompiluje się.
  • Utrata elastyczności i zagmatwana odpowiedzialność.

Pozytywny przypadek

Typowaliśmy callback z opcjonalnym parametrem:

(cb: (x: number, y?: number) => void)

lub zadaliśmy domyślną wartość:

f = (x: number, y = 10) => { ... }

Zalety:

  • Gwarancja braku błędów przy wywołaniu callbacków.
  • Czytelność i łatwość w utrzymaniu.

Wady:

  • Należy uważać na porządek parametrów.