TypeScript Version:
3.4.3
3.4.5
3.5.0-dev.20190430
Search Terms:
Promise.all, array, tuple, as const
Code
// requires `--lib es2017` to run
const p1 = Promise.resolve(1);
const p2 = Promise.resolve('two');
const p3 = Promise.resolve(true);
(async () => {
// works fine
// let [v1, v2, v3] = await Promise.all([p1, p2, p3]);
// also fine
// const promises = [p1, p2, p3] as [typeof p1, typeof p2, typeof p3];
// not fine
const promises = [p1, p2, p3] as const;
let [v1, v2, v3] = await Promise.all(promises);
// quick type test
v1.toExponential();
v2.toUpperCase();
let b: boolean = v3;
})();
Expected behavior:
Promise.all accepts a tuple of Promise objects. Code compiles.
Actual behavior:
An array of promises defined using as const can't be passed to Promise.all. With the latest ts build, I get the following compilation error:
bug.ts:15:42 - error TS2345: Argument of type 'readonly [Promise<number>, Promise<string>, Promise<boolean>]' is not assignable to parameter of type 'Iterable<number | PromiseLike<number>>'.
Types of property '[Symbol.iterator]' are incompatible.
Type '() => IterableIterator<Promise<number> | Promise<string> | Promise<boolean>>' is not assignable to type '() => Iterator<number | PromiseLike<number>>'.
Type 'IterableIterator<Promise<number> | Promise<string> | Promise<boolean>>' is not assignable to type 'Iterator<number | PromiseLike<number>>'.
Types of property 'next' are incompatible.
Type '(value?: any) => IteratorResult<Promise<number> | Promise<string> | Promise<boolean>>' is not assignable to type '(value?: any) => IteratorResult<number | PromiseLike<number>>'.
Type 'IteratorResult<Promise<number> | Promise<string> | Promise<boolean>>' is not assignable to type 'IteratorResult<number | PromiseLike<number>>'.
Type 'Promise<number> | Promise<string> | Promise<boolean>' is not assignable to type 'number | PromiseLike<number>'.
Type 'Promise<string>' is not assignable to type 'number | PromiseLike<number>'.
Type 'Promise<string>' is not assignable to type 'PromiseLike<number>'.
Types of property 'then' are incompatible.
Type '<TResult1 = string, TResult2 = never>(onfulfilled?: (value: string) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>' is not assignable to type '<TResult1 = number, TResult2 = never>(onfulfilled?: (value: number) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
Types of parameters 'value' and 'value' are incompatible.
Type 'string' is not assignable to type 'number'.
15 let [v1, v2, v3] = await Promise.all(promises);
~~~~~~~~
Found 1 error.
Playground Link:
https://www.typescriptlang.org/play/#src=function%20promiseValue%3CT%3E(value%3A%20T)%20%7B%0D%0A%20%20%20%20return%20Promise.resolve(value)%3B%0D%0A%7D%0D%0A%0D%0Aconst%20p1%20%3D%20Promise.resolve(1)%3B%0D%0Aconst%20p2%20%3D%20Promise.resolve('two')%3B%0D%0Aconst%20p3%20%3D%20Promise.resolve(true)%3B%0D%0A%0D%0A(async%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20%2F%2F%20works%20fine%0D%0A%20%20%20%20%2F%2F%20let%20%5Bv1%2C%20v2%2C%20v3%5D%20%3D%20await%20Promise.all(%5Bp1%2C%20p2%2C%20p3%5D)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20also%20fine%0D%0A%20%20%20%20%2F%2F%20const%20promises%20%3D%20%5Bp1%2C%20p2%2C%20p3%5D%20as%20%5Btypeof%20p1%2C%20typeof%20p2%2C%20typeof%20p3%5D%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20not%20fine%0D%0A%20%20%20%20const%20promises%20%3D%20%5Bp1%2C%20p2%2C%20p3%5D%20as%20const%3B%0D%0A%0D%0A%20%20%20%20let%20%5Bv1%2C%20v2%2C%20v3%5D%20%3D%20await%20Promise.all(promises)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20quick%20type%20test%0D%0A%20%20%20%20v1.toExponential()%3B%0D%0A%20%20%20%20v2.toUpperCase()%3B%0D%0A%20%20%20%20let%20b%3A%20boolean%20%3D%20v3%3B%0D%0A%7D)()%3B%0D%0A%0D%0A
TypeScript Version:
3.4.3
3.4.5
3.5.0-dev.20190430
Search Terms:
Promise.all, array, tuple, as const
Code
Expected behavior:
Promise.all accepts a tuple of Promise objects. Code compiles.
Actual behavior:
An array of promises defined using
as constcan't be passed to Promise.all. With the latest ts build, I get the following compilation error:Playground Link:
https://www.typescriptlang.org/play/#src=function%20promiseValue%3CT%3E(value%3A%20T)%20%7B%0D%0A%20%20%20%20return%20Promise.resolve(value)%3B%0D%0A%7D%0D%0A%0D%0Aconst%20p1%20%3D%20Promise.resolve(1)%3B%0D%0Aconst%20p2%20%3D%20Promise.resolve('two')%3B%0D%0Aconst%20p3%20%3D%20Promise.resolve(true)%3B%0D%0A%0D%0A(async%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20%2F%2F%20works%20fine%0D%0A%20%20%20%20%2F%2F%20let%20%5Bv1%2C%20v2%2C%20v3%5D%20%3D%20await%20Promise.all(%5Bp1%2C%20p2%2C%20p3%5D)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20also%20fine%0D%0A%20%20%20%20%2F%2F%20const%20promises%20%3D%20%5Bp1%2C%20p2%2C%20p3%5D%20as%20%5Btypeof%20p1%2C%20typeof%20p2%2C%20typeof%20p3%5D%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20not%20fine%0D%0A%20%20%20%20const%20promises%20%3D%20%5Bp1%2C%20p2%2C%20p3%5D%20as%20const%3B%0D%0A%0D%0A%20%20%20%20let%20%5Bv1%2C%20v2%2C%20v3%5D%20%3D%20await%20Promise.all(promises)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20quick%20type%20test%0D%0A%20%20%20%20v1.toExponential()%3B%0D%0A%20%20%20%20v2.toUpperCase()%3B%0D%0A%20%20%20%20let%20b%3A%20boolean%20%3D%20v3%3B%0D%0A%7D)()%3B%0D%0A%0D%0A