Microsoft właśnie ogłosił release candidate wersji 3.5 TypeScript, czyli ich autorskiej open source’owej odmiany JavaScript wzbogaconej o typy, która docelowo ma zwiększyć kompatybilność i łatwość utrzymania aplikacji JavaScript.
Wersję RC można na ten moment pobrać za pomocą NuGet lub użyć npm i wpisać następującą komendę: npm install -g typecript @ rc.
Jest też dostępny jako pluginy do edytorów Visual Studio 2019/2017, Visual Studio Code i Sublime Text.
Wersja 3.5 ma dla nas kilka nowości, na które warto zwrócić uwagę, ale nie obejdzie się też bez problemów.
TypeScript 3.5 wprowadza kilka optymalizacji wokół kontroli typów i buildów przyrostowych w tym...
W ramach poprawki błędów w TypeScript 3.4, Microsoft przypadkowo wprowadził regresję, która może doprowadzić do eksplozji w ilości pracy, jaką ma do wykonania kontroler typów, a co za tym idzie, czasu ich sprawdzania. Najbardziej dotkniętym tym problemem była grupa użytkowników korzystających z biblioteki Styled-Components. Ta regresja była poważna nie tylko dlatego, że doprowadziła dłuższego procesu budowania kodu w TypeScriptcie, ale dlatego, że operacje edytora dla użytkowników TypeScript i JavaScript stały się nieznośnie powolne.
W wersji 3.5 Microsoft skupił się na optymalizacji niektórych ścieżek w kodzie i usunięciu pewnych funkcji do tego stopnia, że TypeScript 3.5 jest faktycznie szybszy niż TypeScript 3.3 w wielu przypadkach. Czas kompilacji rzekomo nie tylko spadł w porównaniu do 3.4, ale uzupełnienie kodu i wszelkie inne operacje edytora również mają być znacznie szybsze.
TypeScript 3.4 wprowadził nową opcję kompilatora --incremental
. Ta opcja zapisuje kilka informacji w pliku .tsbuildinfo
, który może być użyty do przyspieszenia kolejnych zapytań do tsc
.
TypeScript 3.5 zawiera kilka optymalizacji cachowania obliczeń stanu całego środowiska - ustawienia kompilatora, informacje, dlaczego pliki zostały znalezione, gdzie zostały znalezione itp. Czas rebuildingu został zmniejszony o aż 68% względem wersji 3.4.
W sytuacji, w której celem jest utworzenie obiektu, który omija pewne właściwości, można było wcześniej wyrażać takie typy za pomocą wbudowanych w TypeScript helperów Pick
i Exclude
. Nowy helper Omit
i pozwala na wyłączenie wybranych pół i zwrócenie reszty jako nowego typu.Omit
jest równoważne z wywołaniem Pick
i Exclude
:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
TypeScript ma funkcję nazywaną sprawdzaniem nadmiarowych właściwości w literałach obiektów. Ta funkcja służy do wykrywania literówek, gdy typ nie oczekuje określonej właściwości. W przypadku, w którym zostaje wykryta niespodziewana nazwa w literale, to zostaje zwrócony błąd.
W TypeScript 3.4 i wcześniejszych niektóre nadmiarowe właściwości były dozwolone w sytuacjach, w których tak naprawdę nie powinny były być dozwolone. Np w przypadku tworzenia unii, nie był sprawdzany typ przypisany do właściwości, sprawdzana była tylko nazwa.
type Point = {
x: number;
y: number;
};
type Label = {
name: string;
};
const thing: Point | Label = {
x: 0,
y: 0,
name: true // uh-oh!
};
W TypeScript 3.5 type-checker przynajmniej upewnia się, że wszystkie dostarczone właściwości należą do jakiegoś elementu unii i mają odpowiedni typ, lub zwraca błąd.
Podczas sprawdzania typów przy tworzeniu unii, TypeScript porównuje każdy typ składowy w izolacji.
type S = { done: boolean, value: number }
type T =
| { done: false, value: number }
| { done: true, value: number };
declare let source: S;
declare let target: T;
target = source;
W TS 3.4 powyższy przykład zwróci błąd. W TypeScript 3.5, podczas przypisywania typów takich jak T
, język pójdzie dalej i przedstawi typy takie jak S
jako unię każdego możliwego typu jego właściwości. W tym przypadku, ponieważ boolean
jest unią true
i false
, S
będzie postrzegane jako unia {done:false, value:number}
i {done:true, value:number}
.
W TypeScript 3.4 poprawiono interfejs do tworzenia generycznych funkcji, które zwracają funkcje:
function compose<T, U, V>(
f: (x: T) => U, g: (y: U) => V): (x: T) => V {
return x => g(f(x))
}
W 3.5 pojawiła się możliwość wykorzystania tego podejścia w konstruktorach:
class Box<T> {
kind: "box";
value: T;
constructor(value: T) {
this.value = value;
}
}
class Bag<U> {
kind: "bag";
value: U;
constructor(value: U) {
this.value = value;
}
}
function composeCtor<T, U, V>(
F: new (x: T) => U, G: new (y: U) => V): (x: T) => V {
return x => new G(new F(x))
}
let f = composeCtor(Box, Bag); // has type '<T>(x: T) => Bag<Box<T>>'
let a = f(1024); // has type 'Bag<Box<number>>'
Sami sobie odpowiedzcie czy ta składnia jest czytelna :)
Nie obeszło się oczywiście bez zmian, które nie są kompatybilne z innymi wersjami. Na szczęście Microsoft udostępnia nawet po kilka sposobów na obejście takich ograniczeń. Ostateczna i stabilna wersja TypeScript 3.5 ma pojawić się pod koniec miesiąca.