type Name = string;
type Box<T> = { value: T };
type LinkedList<T> = T & { next: LinkedList<T> };
type Easing = 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
type Truthy = 'enabled' | 'yes' | 'ok' | 'on' | 'true';
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
let rolled: DiceRoll = 9; // TS will mark this as an invalid assignment
T & U
= contains props from both T and U (useful for extends and mixins)id: string | number
= "either or" (useful for function signatures)function extend<T, U> (a: T, b: U): T & U { return Object.assign({}, a, b); }
let foo = { foo: 1, qux: 2 };
let bar = { bar: 1 };
let baz = extend(foo, bar);
This is a bit like overloading, but with the returning type we have less granularity.
let multiply = (source: string | number, times: number = 1): any => {
if (typeof source === 'number') {
return source * times;
}
return (new Array(times)).fill(source).join('');
};
let x: string = multiply('ho', 3);
let y: number = multiply(5, 5);
assert.equal(x + y, 'hohoho25');
strictNullChecks
enabled will disallow assigning null and undefined, unless explicitly allowedlet foo = 'bar';
let name: string | null;
foo = null; // not allowed with strictNullChecks
name = null; // we did let null to be assigned
interface X {
a: number;
b?: number; // same as `number | undefined`
}
🚀 Writing better typechecks with the "is" keyword:
interface Fish { swim: boolean; name: string; }
interface Bird { fly: boolean; name: string; }
let myBird: Bird = { name: 'Tweetie', fly: true };
let myFish: Fish = { name: 'Wanda', swim: true };
let pets = [ myBird, myFish ];
// item is Type
// ↓
function isFish (pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}