TypeScript

Piotr Lewandowski

must know for Java devs ❤️

Be open - new is coming

✌️

 

 

TypeScript

About TypeScript

  • released in 2012

  • inherited from Java / C#

  • classes, interfaces, modules, generics, enums

  • compiled, result in JS code

  • maintained by Microsoft & Google

(Great summary by Tomasz Ducin)

TypeScript = JS + types

TS code example

// api.service.ts

const PATH: string = "rest/";

export function http<T>(url: string): Observable<T> {
    // make Http call
}
// component.ts

import { http } from "./api.service";


http<string[]>("/heroes")
  .subscribe(heroes => console.log(heroes));

Main sell points

😍 IDE support & tooling

😍 Very close to ES standard = future-proof

😍 External libraries support

😍 Compiles newset JS to ES5

npm i install lodash
npm i install @types/lodash

 

TS vs Java

JavaScript

  • dynamic typing
  • weak typing
  • single-thread
    async
  • functional
  • prototype-based

Java

  • static typing
  • strong typing
  • multi-thread
    synchronous
  • Object-oriented
  • class-based

TypeScript

(Great summary by Tomasz Ducin)

Classes

Java

class HeroModel {
    private final String name;

    public HeroModel(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

HeroModel model = new HeroModel("Marvel");
model.getName();

Classes

TypeScript

class HeroModel {
    private readonly name: string;

    public constructor(name: string) {
        this.name = name;
    }

    public getName(): string {
        return this.name;
    }
}

const api = new HeroModel("Marvel");
api.getName();

Classes without getters

TypeScript

class HeroModel {
    public readonly name: string;

    public constructor(name: string) {
        this.name = name;
    }
}

const api = new HeroModel("Marvel");
api.name;

Classes without getters

TypeScript

class HeroModel {
    private _name: string;

    public constructor(name: string) {
        this._name = name;
    }
    
    public get name(): string {
        // code ... logic? lazy-loading?
        return this._name;
    }
}

const api = new HeroModel("Marvel");
api.name;

Classes

are not always needed

interface HeroModel {
    readonly name: string;
}

const api: HeroModel = {
    name: "Marvel"
};

Structural typing

Biggest difference!

class Duck {
  void quack() { 
    // ... 
  }
}

class WildDuck {
  void quack() { 
    // ... 
  }
}

WildDuck hero =
    new Duck(); // !ERR
class Duck {
  quack(): void { 
    // ... 
  }
}

class WildDuck {
  quack(): void { 
    // ... 
  }
}

WildDuck hero =
    new Duck(); // OK

Null safety

Java

Null safety by default

TypeScript

Null safety by default

TypeScript

Dependency Injection

Java

Dependency Injection

TypeScript

Easier immutable objects

interface Hero {
  isAlive: boolean;
  power: string;
}

const hero: Readonly<Hero> = {
  isAlive: true,
  power: "strength",
};

hero.isAlive = false; // ERR!
const deadHero: Readonly<Hero> = {
  ... hero,
  isAlive: false,
};

Easier immutable lists

const values: ReadonlyArray<number> = [1, 2, 3];

a.push(4); // ERR!
a.sort(); // ERR!
const doubled = values.map(i => i * 2); // OK

const withZero = [0, ... values]

Why?

objects are more often comparing than changeing

In front-end...

objects have longer live cycle

comparison by reference is faster

so they are more exposed on unwanted change

🔒

JS collections API

const uniqueNumbers = new Set([1, 2, 3, 3]);

[...uniqueNumbers]; // [1, 2, 3]
const esVersions = new Map([
  ["es5", 2012],
  ["es6", 2015],
  ["es7", 2016],
]);

for (const [key, value] of esVersions.entries()) {
  // ...
}

Streams vs JS

// Java

Arrays.newArrayList(1, 2, 3).stream()
    .filter(i -> i < 3)
    .map(i -> i * 2)
    .collect(Collectors.toList());
// JS

[1, 2, 3]
    .filter(i => i < 3)
    .map(i -> i * 2);

Type  System

Everything is a type

type Pair = [number, number]

const points: Pair[] = [
    [0, 0],
    [1, 5]
]
// Types can be combined
type Pairs = Pair[];

Everything is a type

interface AddressForm {
    street: string;
}

interface PersonForm {
    name: string;
}
type Form = AddressForm & PersonForm;

const initialForm: Form = {
    name: "Sherlock",
    street: "Baker Street",
};

Type overloading

create(queryParam: string): GlobalTimeFrame {
    // ... creating objects with different types
}
create(queryParam: "l"): LastTimeFrame;
create(queryParam: "c"): CustomTimeFrame;
create(queryParam: string): NotValidTimeFrame;

Context-types

 

 

JavaScript

JavaScript is just
pile of mistakes...

JS Bad Parts

Global variables

✔️Fixed by ES 2015 modules

Function scopes

✔️Fixed by let / const in ES 2015

`this` semantic

✔️Fixed by classes & arrow functions

JS Bad Parts

Phony arrays / reflection

const a = []
a[77] = "";
a.length // 78

❌ Not fixed by language

✔️ Fixed by TS linting rules

JS Bad Parts

WAT parts

{} + {}
[] + []
"hey" * 2

✔️ Fixed by TypeScript

JS Bad Parts

WAT parts

typeof

typeof {} // [Object object]
typeof [] // [Object object]
typeof null // [Object object]

✔️ Fixed by TypeScript

✔️ Fixed by TS linting rules

TS bad parts 😱

No bullshit policy

Requires learning JavaScript way!

No types in runtime

Classes

not as advanced

as in Java

Enums

not very convenient

JS stdlib

smaller than Java

 

End of File.

@constjs

TypeScript The Good Parts

By Piotr Lewandowski

TypeScript The Good Parts

  • 306