Less known parts
for people in hurry
Piotr Lewandowski
interface FoodDelivery {
orderPizza(ingrediens: any): any;
}
pizzaMaker.orderPizza(
"ananas"
);
Extend library
pizzaMaker.orderPizza("ananas");
declare interface FoodDelivery {
orderPizza(ingrediens: string[]): number;
orderPizza(ingrediens: string): number;
}
declare var pizzaMaker: FoodDelivery;
Describes JavaScript
Static typing
State of the ar
Static != Strong
Java / C# | static and strong typing |
TypeScript | static and weak typing |
JavaScript | dynamic and weak typing |
class JavaGroup {
id : number = 1;
hour : string = "13:30";
}
class FrontendGroup {
id: number = 2;
hour: string = "14:30"
}
let skm: JavaGroup =
new JavaGroup();
Structural typing
skm = new FrontendGroup();
let isJava =
skm instanceof JavaGroup;
skm = {
id: 3,
name: ".Net",
hour: "15:30?"
};
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;
x(1);
y(1, "2");
Structural typing
y = x; // OK
x = y; // Error
class RequestBuilder {
get(): RequestBuilder {
// set some params;
return this;
}
}
class CrudRequest
extends RequestBuilder {
post() : CrudRequest {
return this;
}
delete() : CrudRequest {
return this;
}
}
let request = new CrudRequest()
.post()
.get()
.delete();
// ??? No method found
// on type 'RequestBuilder'
Polymorphic this
class RequestBuilder {
get(): this {
// set some params;
return this;
}
}
class CrudRequest
extends RequestBuilder {
post() : this {
return this;
}
delete() : this {
return this;
}
}
let request = new CrudRequest()
.post()
.get()
.delete();
// :)
Polymorphic this
keyof
interface Point {
x: number;
y: number;
}
type Dimensions = keyof Point; // "x" | "y"
let dimension : Dimensions = "z" // Error;
interface PizzaIngredients {
peperoni: boolean;
doubleCheese: boolean;
sauce: "ketchup" | "garlic";
}
const pizza: PizzaIngredients = {
peperoni: true,
doubleCheese: true,
sauce: "ketchup"
};
const value = pizza['peperoni'];
var pizza = {
peperoni: true,
doubleCheese: true,
sauce: "ketchup"
};
var value = pizza['peperoni'];
Problem
Element implicitly has an 'any' type
because type 'PizzaIngredients'
has no index signature.
interface PizzaIngredients {
peperoni: boolean;
doubleCheese: boolean;
sauce: "ketchup" | "garlic";
}
const pizza: PizzaIngredients = {
peperoni: true,
doubleCheese: true,
sauce: "ketchup"
};
let key: string = 'peperoni';
let value: string = (pizza as any)[key];
interface PizzaIngredients {
peperoni: boolean;
doubleCheese: boolean;
[key: string]: boolean;
}
let key: string = 'peperoni';
let value: boolean = pizza[key];
let key: keyof PizzaIngredients = 'peperoni';
let value: boolean = pizza[key];
interface Configuration {
baseUrl: string;
port: number;
}
type ConfigurationOption = keyof Configuration; // 'baseUrl' | 'port'
Mapped types
type ConfigurationLastUpdated = {
[O in ConfigurationOption]: Date
};
const updated: ConfigurationLastUpdated = {
baseUrl: new Date(),
port: new Date()
};
type Color = 'red' | 'blue' | 'green';
type ColorToRgb = {
[C in Color]? : string;
};
Mapped types
const rgbMap: ColorToRgb = {
red: '#ff0000'
};
Generic types
function httpGet(): Promise<string> {
return Promise.resolve("ok");
}
httpGet()
.then(data => data.toUpperCase());
interface PromiseConstructor {
// ...
resolve<T>(value: T | PromiseLike<T>): Promise<T>;
}
[0, 1, "2"]
interface PromiseConstructor {
// ...
all<T1, T2, T3>(values: [T1, T2, T3]): Promise<[T1, T2, T3]>;
}
interface Point {
x : integer;
y : integer;
}
type PartialPoint = Partial<Point>;
// =>
interface PartialPoint {
x? : integer;
y? : integer;
}
type PartialPoint = {
[P in keyof Point] ?: Point[P];
};
Generic + mapped
type PartialPoint = {
[P in "x" | "y"] ?: Point[P];
};
type PartialPoint = {
x? : Point["x"];
y? : Point["y"];
};
type PartialPoint = {
x? : number;
y? : number;
};
<type assertion>
not casting
let mouseEvent = <MouseEvent> event;
let mouseEvent = event as MouseEvent;
Double casting
function handler (event: Event) {
let mouseEvent = event as MouseEvent;
}
function handler(event: Event) {
let element = event as HTMLElement; // Error
}
function handler(event: Event) {
let element = event as any as HTMLElement; // OK
}
type guards
next time maybe :)
function counter(state = 0, action: Action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
Redux
Further reading
- TypeScript roadmap
- Mapped types examples
- Read lib.d.ts
TypeScript less known part
By Piotr Lewandowski
TypeScript less known part
We talk about typing system, which is more advanced than Java or C#.
- 322