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.
TypeScript The Good Parts
By Piotr Lewandowski
TypeScript The Good Parts
- 306