Piotr Lewandowski
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)
// 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));
😍 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
(Great summary by Tomasz Ducin)
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();
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();
TypeScript
class HeroModel {
public readonly name: string;
public constructor(name: string) {
this.name = name;
}
}
const api = new HeroModel("Marvel");
api.name;
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;
are not always needed
interface HeroModel {
readonly name: string;
}
const api: HeroModel = {
name: "Marvel"
};
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
Java
TypeScript
TypeScript
Java
TypeScript
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,
};
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]
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
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()) {
// ...
}
// 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 Pair = [number, number]
const points: Pair[] = [
[0, 0],
[1, 5]
]
// Types can be combined
type Pairs = Pair[];
interface AddressForm {
street: string;
}
interface PersonForm {
name: string;
}
type Form = AddressForm & PersonForm;
const initialForm: Form = {
name: "Sherlock",
street: "Baker Street",
};
create(queryParam: string): GlobalTimeFrame {
// ... creating objects with different types
}
create(queryParam: "l"): LastTimeFrame;
create(queryParam: "c"): CustomTimeFrame;
create(queryParam: string): NotValidTimeFrame;
JavaScript is just
pile of mistakes...
✔️Fixed by ES 2015 modules
✔️Fixed by let / const in ES 2015
✔️Fixed by classes & arrow functions
const a = []
a[77] = "";
a.length // 78
❌ Not fixed by language
✔️ Fixed by TS linting rules
{} + {}
[] + []
"hey" * 2
✔️ Fixed by TypeScript
WAT parts
typeof {} // [Object object]
typeof [] // [Object object]
typeof null // [Object object]
✔️ Fixed by TypeScript
✔️ Fixed by TS linting rules
No bullshit policy