I will use a contrived example.
We need to increment some numbers. Given an integer x
, our function should return x + 1
.
Programmer 1 reads the requirements and creates the following implementation:
interface Thenable<T> { | |
then<U>(onResolve: (value: T) => U, onReject: (error: any) => Thenable<U>): Thenable<U> | |
then<U>(onResolve: (value: T) => Thenable<U>, onReject: (error: any) => Thenable<U>): Thenable<U> | |
} | |
const client: Thenable<string> = { | |
async then(resolve: (value: string) => Promise<string>, reject: (error: string) => Promise<string>) { | |
return Math.random() > 0.5 | |
? resolve('Success!') | |
: reject('Failure!') |
type Comparator<T> = (x: T, y: T) => Comparison; | |
enum Comparison { | |
LessThan = -1, | |
Equal = 0, | |
GreaterThan = 1, | |
} | |
function search<T>(array: T[], item: T, compare: Comparator<T>): number { | |
let [left, right] = [0, array.length - 1]; |
function visit(node: Element, callback: (element: Element) => void): void { | |
callback(node); | |
Array | |
.from(node.children) | |
.forEach(child => visit(child, callback)); | |
}; | |
visit(document.body, console.log); |
function sum(x: number): (y: number) => number; | |
function sum(x: number, y: number): number; | |
function sum(x: number, y?: number): ((y: number) => number) | number { | |
if (y === undefined) { | |
return (y: number) => x + y; | |
} | |
return x + y; | |
// This also works: |
// 1. Let's define a tuple of country codes. | |
const countries: [string, string] = ["es", "ko"]; | |
// 2. Good! We know the returned tuple will only have two elements. | |
const [spanish, korean, valyrian] = | |
countries.map(country => new Intl.DateTimeFormat(country)); | |
// 3. We know `valyrian` doesn't exist! | |
valyrian.format(new Date()); |
type NonEmptyArray<T> = [T, ...T[]]; | |
const hasElements = <T>(collection: T[]): collection is NonEmptyArray<T> => | |
collection.length > 0; | |
const head = <T>(collection: NonEmptyArray<T>): T => | |
collection['0']; | |
const tail = <T>(collection: T[]): T[] => { | |
const [_, ...tail] = collection; |
type ContentType = 'application/x-www-form-urlencoded' | 'application/json'; | |
/** | |
* POJO payloads used to make PUT and POST requests made with `fetch` | |
* need to be converted to a format `fetch` accepts first. | |
*/ | |
export const serialize = (payload: object, type: ContentType): string => { | |
switch (type) { | |
case 'application/x-www-form-urlencoded': | |
return Object.entries(payload) |
declare class CSSPropertyManager<T> { | |
has<K extends keyof T>(property: K): asserts this is CSSPropertyManager<T & Required<T, K>; | |
get<K extends keyof T>(property: K): boolean; | |
set(property: keyof T, value: string): this; | |
} | |
const schema = { | |
'--width-1': string; | |
} |