programowanieProgramista Backend

Jak opcjonalne parametry funkcji i opcjonalne właściwości obiektów działają w TypeScript, czym się różnią i jakie są niuanse ich stosowania? Podaj przykłady typowych problemów i błędów.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Opcjonalne parametry funkcji są wskazywane za pomocą znaku zapytania (?) po nazwie parametru. To samo dotyczy opcjonalnych właściwości w obiektach (interfejsach lub typach).

  • Dla funkcji:
function greet(name?: string) { console.log(`Hello, ${name ?? 'stranger'}`); } greet(); // Hello, stranger greet('John'); // Hello, John
  • Dla obiektów:
interface User { id: number; nickname?: string; } const u1: User = { id: 1 }; const u2: User = { id: 2, nickname: 'Bob' };

Niuanse:

  • Opcjonalny parametr — można go nie przekazać przy wywołaniu funkcji, a wartość będzie undefined.
  • Opcjonalna właściwość — taka właściwość może brakować w obiekcie.
  • Nie myl: jeśli w interfejsie właściwość nie jest określona jako opcjonalna, jest obowiązkowa!
  • Opcjonalny parametr musi znajdować się na końcu listy argumentów funkcji.

Pytanie z pułapką.

Jeśli funkcja jest zadeklarowana z opcjonalnym parametrem typu string (function fn(x?: string)), czy można ją jawnie wywołać z undefined? Czym różni się fn() od fn(undefined)?

Odpowiedź: Tak, można wywołać z undefined: fn(undefined) i fn() — wynik jest taki sam, ale wewnątrz funkcja otrzyma x === undefined. Ale jeśli zdefiniowano wartość domyślną w sygnaturze:

function fn(x: string = 'demo') { console.log(x); } fn(); // demo fn(undefined); // demo fn('abc'); // abc

A jeśli argument nie jest oznaczony jako opcjonalny (brak ? lub wartości domyślnej), wywołanie fn() zakończy się błędem kompilacji.

Przykłady rzeczywistych błędów z powodu niewiedzy na temat niuansów tematu.


Historia

W interfejsie użytkownika podano właściwość phone: string (bez ?), ale zapomniano ją dodać podczas tworzenia instancji obiektu. W efekcie kompilator TypeScript zaczął zgłaszać błąd z powodu braku obowiązkowej właściwości. Tymczasowym rozwiązaniem było dodanie phone: undefined, ale to było sprzeczne z typem, ponieważ string !== undefined, co spowodowało jeszcze więcej błędów walidacji.


Historia

Zdefiniowano kilka opcjonalnych parametrów w funkcji, ale umieszczono je nie na końcu listy argumentów. TypeScript zgłosił błąd, a po przestawieniu parametrów zmieniła się kolejność odpowiednich przekazanych wartości do parametrów, co doprowadziło do zamieszania i nieprawidłowego działania funkcji.


Historia

Opcjonalne pola w interfejsach zostały pominięte podczas opisywania typu danych dla zewnętrznego API (np. nazwisko klienta? string), przez co przy zmianie schematu z jednej strony te pola przestały napływać, a z drugiej — kod zaczął się psuć przy próbie ich odczytu bez sprawdzenia na undefined.