W TypeScript tablice opisuje się na dwa główne sposoby: typ[] oraz Array<typ>. Dla tablic z elementami różnych typów używa się typów unijnych (union types) lub krotek (tuples), które pozwalają opisywać ustalony zestaw elementów różnych typów i ilości.
Deklaracje tablic:
let numbers: number[] = [1, 2, 3]; let strings: Array<string> = ['a', 'b', 'c'];
Tablica z elementami różnych typów:
let mixed: (string | number)[] = [1, 'a', 2];
Krotki (tuples):
let tuple: [string, number, boolean] = ['hello', 42, true];
Z krotkami łatwiej pracować, gdy oczekuje się ustalonej struktury (na przykład, aby zwrócić z funkcji kilka różnych wartości typu jednocześnie), natomiast z tablicami — gdy liczba i typ elementów mogą być pomieszane lub nieznane z góry.
Czy po zdefiniowaniu krotki o długości N można dodać do niej elementy za pomocą push? Jak to wpływa na typizację?
Odpowiedź: Tak, można dodawać do krotki elementy — kompilator na to zezwala, chociaż narusza to założenie ograniczenia długości krotki. Typy nowych elementów będą rzutowane na union wszystkich możliwych typów elementów krotki:
let tuple: [number, string] = [42, 'foo']; tuple.push(true); // OK! tuple teraz: [number, string, boolean], ale typ się nie zaktualizował, a błędu nie ma! console.log(tuple); // [42, 'foo', true]
Dlatego pracując z krotkami i ich zmiennością, należy to kontrolować ręcznie lub uczynić je readonly.
Historia
Programista opisał funkcję, która zwraca krotkę [number, string], ale potem zaczął dodawać do wyniku elementy przez push. Doprowadziło to do rozbieżności typów: późniejszy kod oczekiwał dokładnie dwóch elementów o określonych typach, ale otrzymywał tablicę o zmiennej długości, co prowadziło do błędów w czasie wykonywania podczas rozpakowywania wartości i odczytu z nieistniejących indeksów.
Historia
Do przechowywania tablicy wartości różnych typów użyto tablicy any[], uważając to za uniwersalne rozwiązanie. W rezultacie TypeScript przestał sprawdzać poprawność typów, a logika aplikacji zaczęła "łamana" przez niepoprawne przekształcenia typów, które nie powodowały błędów kompilacji.
Historia
W projekcie tablica była opisywana albo przez typ[], albo przez Array<typ> — ale w niektórych miejscach dopuszczano zapis let arr: any[] (aby pracować "z czymkolwiek"). Z tego powodu pojawiały się niekontrolowane przekształcenia, funkcja przyjmowała każdą tablicę, co prowadziło do błędów w czasie wykonywania podczas próby wywołania niepoprawnych metod dla elementów różnych typów.