/** * Notes about these type definitions: * * - Callbacks returning multiple completion values using multiple arguments are not supported by these types. * Prefer to use Node's style by grouping your values in a single object or array. * Support for this kind of callback is blocked by Microsoft/TypeScript#5453 * * - For ease of use, `asyncDone` lets you pass callback functions with a result type `T` instead of `T | undefined`. * This matches Node's types but can lead to unsound code being typechecked. * * The following code typechecks but fails at runtime: * ```typescript * async function getString(): Promise { * return "Hello, World!"; * } * * async function evilGetString(): Promise { * throw new Error("Hello, World!"); * } * * function cb(err: Error | null, result: string): void { * // This is unsound because `result` is `undefined` when `err` is not `null`. * console.log(result.toLowerCase()); * } * * asyncDone(getString, cb); // Prints `hello, world!` * asyncDone(evilGetString, cb); // Runtime error: `TypeError: Cannot read property 'toLowerCase' of undefined` * ``` * * Enforcing stricter callbacks would require developers to use `result?: string` and assert the existence * of the result either by checking it directly or using the `!` assertion operator after testing for errors. * ```typescript * function stricterCb1(err: Error | null, result?: string): void { * if (err !== null) { * console.error(err); * return; * } * console.log(result!.toLowerCase()); * } * * function stricterCb2(err: Error | null, result?: string): void { * if (result === undefined) { * console.error("Undefined result. Error:); * console.error(err); * return; * } * console.log(result.toLowerCase()); * } * ``` */ import { ChildProcess } from 'child_process'; import { EventEmitter } from 'events'; import { Stream } from 'stream'; declare namespace asyncDone { /** * Represents a callback function used to signal the completion of a * task without any result value. */ type VoidCallback = (err: Error | null | void) => void; /** * Represents a callback function used to signal the completion of a * task with a single result value. */ interface Callback { (err: null, result: T): void; // Use `result?: T` or `result: undefined` to require the consumer to assert the existence of the result // (even in case of success). See comment at the top of the file. (err: Error, result?: any): void; } /** * Minimal `Observable` interface compatible with `async-done`. * * @see https://github.com/ReactiveX/rxjs/blob/c3c56867eaf93f302ac7cd588034c7d8712f2834/src/internal/Observable.ts#L77 */ interface Observable { subscribe( next?: (value: T) => void, error?: (error: any) => void, complete?: () => void ): any; } /** * Represents an async operation. */ export type AsyncTask = | ((done: VoidCallback) => void) | ((done: Callback) => void) | (() => | ChildProcess | EventEmitter | Observable | PromiseLike | Stream); } /** * Takes a function to execute (`fn`) and a function to call on completion (`callback`). * * @param fn Function to execute. * @param callback Function to call on completion. */ declare function asyncDone( fn: asyncDone.AsyncTask, callback: asyncDone.Callback ): void; export = asyncDone;