| // Like Object.values but with a stronger return type. |
| export function values<T extends {[key: string]: any}, K extends keyof T>( |
| o: T |
| ): Required<T>[K][] { |
| return Object.values(o); |
| } |
| |
| // Like Object.entries but with a stronger return type. |
| export function entries<T extends {[key: string]: any}, K extends keyof T>( |
| o: T |
| ): [keyof T, Required<T>[K]][] { |
| return Object.entries(o); |
| } |
| |
| // Wraps text to the given maximum width, preserving existing newlines. |
| export function wordWrap(text: string, width: number): string { |
| function wrap(line: string): string { |
| const words = line.split(' '); |
| let lineLength = 0; |
| const withNewlines = words.map(w => { |
| lineLength += w.length + 1; |
| if (lineLength > width) { |
| lineLength = w.length; |
| return '\n' + w; |
| } |
| return w; |
| }); |
| return withNewlines.join(' '); |
| } |
| const lines = text.split('\n'); |
| return lines.map(wrap).join('\n'); |
| } |
| |
| // A type for timeout IDs. |
| export type Timeout = ReturnType<typeof setTimeout>; |
| |
| // Wraps a promise with a timeout, in milliseconds. |
| export function withTimeout<T>( |
| ms: number, |
| errMsg: string, |
| promise: Promise<T> |
| ): Promise<T> { |
| return new Promise((resolve, reject) => { |
| const timeout = setTimeout(() => { |
| reject(new Error(errMsg)); |
| }, ms); |
| promise.then( |
| (res: T) => { |
| clearTimeout(timeout); |
| resolve(res); |
| }, |
| err => { |
| clearTimeout(timeout); |
| reject(err); |
| } |
| ); |
| }); |
| } |