type Transform>> = (x: T) => U; type TransformChain>> = { (x: T): U; use(transform: Transform): () => void; }; export const createAsyncTransformChain = ( ...transforms: Transform>>[] ): TransformChain>> => { let chain = transforms; const call = (x: T): Promise> => chain.reduce((x, transform) => x.then(transform), Promise.resolve(x)); const use = (transform: Transform>>): (() => void) => { chain.push(transform); return (): void => { chain = chain.filter((t) => t !== transform); }; }; return Object.assign(call, { use }); };