TypeScript ist in der heutigen JavaScript-Welt ein immer wieder auftauchender Bestandteil. Mit TypeScript 2.0 wurde der Grundstein gelegt, die Sprache endgültig in das bestehende JavaScript-Tooling mit npm zu integrieren. In dieser Livecoding-Session werden wegweisende Features vorgestellt. Darunter die immer bessere Control-Flow-Analyse zur Typinferenz als auch Non-nullable Types, Sprachkonstrukte für besseres OOP und ganz neue Typen wie never. Ein weiteres Thema sind die ESNext-Features, wie Async/Await und Decorators, die schon heute nach ES3/ES6 transpiliert werden können.
6. The never type (1)
class PseudoAbstractClass {
pseudoAbstractMethod(): never {
throw new Error();
}
}
// Leads to error:
// Class 'SubClass' incorrectly extends base class 'PseudoAbstractClass'
class SubClass extends PseudoAbstractClass {
pseudoAbstractMethod() {
return 42;
}
}
6 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
7. The never Type (2)
• The never type is the bottom type of the type hierarchy
• It signals that a method does not return
• The compiler uses it mostly to prevent errors
const foo = () => { throw new Error()};
let bar = foo();
bar. // no suggestions
7 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
8. Control-Flow Analysis (1) – Determine type
function notNullTest(x: string | null) {
if (x === null) {
return;
}
x; // type of x is string in remainder of function
}
function test(title: any) {
if (typeof title == 'string') {
// Property 'filter' does not exist on type 'string'.
title.filter((t) => t == 'foo');
}
}
8 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
9. Control-Flow Analysis (2) – Prevent compile errors
if (false) {
// @ts-ignore: Unreachable code error
console.log("hello");
}
9 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
10. Control-Flow Analysis (3) - NoImplicitAny
// Parameter 'title' implicitly has an 'any' type.
function implicitAny(title) {
title.filter();
}
// No error
function implicitAny(title: { filter: () => void; }) {
title.filter();
}
10 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
11. Control-Flow Analysis (4) – Type widening
const c1 = 1; // Type 1
const c2 = c1; // Type 1
const c3 = "abc"; // Type "abc"
const c4 = true; // Type true
const c5 = (42) ? 1 : "abc"; // Type 1 | "abc"
let v1 = 1; // Type number
let v2 = c2; // Type number
let v3 = c3; // Type string
let v4 = c4; // Type boolean
let v5 = c5; // Type number | string
11 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
12. Control-Flow Analysis (5) – Generics
let x: Promise<string> = new Promise(resolve => {
// resolve(10); ~~ Error!
resolve("10");
});
let fun1: <T>(x: T) => T = y => y;
// Leads to errors, because y is of type T
let fun2: <T>(x: T) => T = y => y() + y.foo.bar;
type A = <T, U>(x: T, y: U) => [T, U];
type B = <S>(x: S, y: S) => [S, S];
function fun3(a: A, b: B) {
// a = b; // Error
b = a; // Ok
return b;
}
12 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
13. Control-Flow Analysis (6) – Definite Assignment Operator
let x: number;
console.log(x); // Error: Variable is used before assignment
let y!: number;
console.log(y); // No Error
13 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
14. Control-Flow Analysis (7) – Fixed length Arrays
let anArray: [number, number] = [27, 42];
// Error: Type [number, number, number]
// not assignable to [number, number]
anArray = [1, 2, 3];
14 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
15. Class based Mixins (1)
type Constructor<T = {}> = new(...args: any[]) => T;
function Tagged<T extends Constructor>(Base: T) {
return class extends Base {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "";
}
}
}
15 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
16. Class based Mixins (2)
class Developer {
constructor(public name: string, language: string) {}
}
class DevOpsGuy extends Tagged(Developer) {
operating_system: string;
}
let devopsguy = new DevOpsGuy("Joe", "Doe");
devopsguy._tag = "The chosen one";
devopsguy.operating_system = "Linux";
16 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
17. Class based Mixins (3)
const WithSoundBite = <T extends Constructor<Developer>>(Base: T) =>
class extends Base {
getSoundBite(): string {
return `${this.language} is the best!`;
}
}
class SoundBiter extends WithSoundBite(Developer) { }
let sB = new SoundBiter("Jane", "Dane");
sB.getSoundBite();
17 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
18. Decorators (1)
• A decorator is a function with the following signature
function dec(target: any, propertyKey: any, descriptor: any) { }
• Applicable to classes, methods and parameters
18 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
19. Decorators (2) – Example https://github.com/awerlang/es-decorators
const serialized = new WeakMap();
export function serializable() {
return function (target: any) {
target.prototype.toJSON = function () {
const map = serialized.get(target.prototype);
const props = Object.keys(map);
return props.reduce((previous, key) => {
previous[map[key]] = this[key];
return previous;
}, {});
}
}
}
19 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
20. Decorators (3) – Example https://github.com/awerlang/es-decorators
export function serialize(name?: string) {
return function (target, propertyKey) {
let map = serialized.get(target);
if (!map) {
map = {};
serialized.set(target, map);
}
map[propertyKey] = name || propertyKey;
}
}
20 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
21. Decorators (4) – Example https://github.com/awerlang/es-decorators
@serializable()
class Person {
constructor(name: string) {
this._name = name;
}
private _name: string;
@serialize()
get name() {
return this._name;
}
}
const p = new Person('Johannes');
console.log(JSON.stringify(p));
21 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
22. Async / Await (1)
function delay(milliseconds: number) {
return new Promise<void>(resolve => {
setTimeout(resolve, milliseconds);
});
}
async function dramaticWelcome() {
console.log("Hello");
for (let i = 0; i < 3; i++) {
await delay(500);
console.log(".");
}
console.log("World!");
}
22 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
23. Async / Await (2)
async function* g() {
yield 1;
await delay(100);
yield* [2, 3];
yield* (async function *() {
await delay(100);
yield 4;
})();
}
async function fun() {
for await (const x of g()) {
console.log(x);
}
}
23 DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst
24. I love working with smart people and being challenged.
I also like working on stuff that‘s relevant.
That‘s my adrenaline shot.
Anders Hejlsberg
DB Systel GmbH | Johannes Dienst | T.IPI 42 | @JohannesDienst