TypeScript
Typing
- TypeScript is structural typing.
- Java and C++ are nominal typing.
type Foo = {};
type Bar = {};
let foo: Foo = {};
let bar: Bar = {};
// This is perfectly valid in TypeScript
bar = foo;
Type vs. Interface
// Literals
type car = 'Volvo' | 'BMW'
// Unions
type car = { brand: 'volvo' } | { brand: 'bmw'; year: 1994 };
// Tupels
type Point = [number, number];
// Mapped
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
literals vs. enum
type Direction = "North" | "South"
// —> compiles to nothing
enum Direction {
North,
South,
}
// —> compiles to
{
1: «North»,
2: «South»
}
How to limit generics?
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, 'a'); // okay
getProperty(x, 'm'); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
Mapped Types
type CustomReadonly<T> = {
readonly [K in keyof T]: T[K];
};
Utility Types
Partial<T>
– optionalRequired<T>
– requiredPick<T, K extends keyof T>
– take oneOmit<T, K extends keyof T>
– remove oneRecord<Keys extends keyof any, Values>
– create object
And rest…
type CustomPartial<T> = {
[K in keyof T]?: T[K];
};
unknown vs. any vs. never
unknown
asks for checking before usageany
don’t- example of
never
is throwing an error
keyof, typeof, and instanceof
keyof
return keys of typetypeof
return type of variableinstanceof
checks prototype chain if same constructor appear
Discriminated Unions
One type is set of other types.
Each type has a unique discriminant property.
type TextMessage = { kind: 'text'; content: string };
type ImageMessage = { kind: 'image'; src: string };
type Message = TextMessage | ImageMessage;