Historia pytania:
Union types pojawiły się w TypeScript w celu opisu zmiennych i parametrów, które mogą przyjmować wartości różnych typów. Ta możliwość znacznie rozszerzyła elastyczność typizacji w porównaniu z klasycznymi językami.
Problem:
W JavaScript funkcje i zmienne często mają wiele formatów (na przykład przyjmują liczbę lub tekst), co komplikuje bezpieczną typizację. Bez union types trzeba było używać typu any lub dublować kod. To zwiększało liczbę błędów w produkcie i utrudniało pracę w dużych zespołach.
Rozwiązanie:
Union types pozwalają zadeklarować zmienną, która może być jednym z kilku typów, gwarantując poprawne operacje po sprawdzeniu. Zrealizowano również wsparcie dla zawężania typów (type narrowing), co pomaga kompilatorowi „zrozumieć”, z czym ma do czynienia.
Przykład kodu:
function formatId(id: number | string): string { if (typeof id === 'string') { return id.toUpperCase(); } return id.toString(); }
Kluczowe cechy:
Czy można zapisać union z obiektami o różnych właściwościach i odwoływać się do dowolnej właściwości bez sprawdzenia?
Nie. Union types pozwalają odwoływać się tylko do tych właściwości i metod, które są obecne we wszystkich typach. Aby uzyskać dostęp do prywatnych właściwości, wymagana jest zawężenie typu.
Przykład kodu:
type Fish = { swim: () => void; }; type Bird = { fly: () => void; }; function move(animal: Fish | Bird) { // animal.swim(); // Błąd bez zawężenia if ('swim' in animal) { animal.swim(); // OK } }
Dlaczego nie wszystkie metody są dostępne dla union typu string | number?
TypeScript w union pozwala tylko na to, co jest we wszystkich uwzględnionych typach. Aby używać indywidualnych metod, należy najpierw sprawdzić rzeczywisty typ.
Co się stanie, jeśli nie sprawdzasz typu w union, a spróbujesz wywołać specyficzną metodę?
W takim przypadku wystąpi błąd kompilacji, ponieważ nie gwarantuje się obecności metody. Działa to tylko po sprawdzeniu konkretnego typu.
Zmienna otrzymała typ string | number i bez sprawdzenia wywołano toUpperCase(). W rezultacie aplikacja się zawiesza przy danych numerycznych.
Zalety:
Wady:
Sprawdzamy typ przed pracą z metodą:
if (typeof value === 'string') { return value.toUpperCase(); } else { return value.toString(); }
Zalety:
Wady: