Description
Hello everyone,
Not sure if this is the correct place to bring this up but the Awaited<T>
type as-is broke our build after upgrading from typescript 4.4.3 to 4.5.2.
For reference, here is what Awaited<T>
looks like:
/**
* Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`.
*/
type Awaited<T> =
T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F): any } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
F extends ((value: infer V) => any) ? // if the argument to `then` is callable, extracts the argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T; // non-object or non-thenable
The problem is that we have a custom Promise class (AbortablePromise
) and its then
function accepts a onfulfilled
callback that do not exactly match the condition F extends ((value: infer V) => any)
.
Our then
is declared like this:
public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T, abortController: AbortController) => TResult1 | PromiseLike<TResult1>) | undefined | null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
): AbortablePromise<TResult1 | TResult2>;
So onfulfilled
in our case is (value: T, abortController: AbortController) => TResult1 | PromiseLike<TResult1>)
which does not match (value: infer V) => any
Hence, Awaited<T>
where T
is an AbortablePromise
always returns never
.
Would it be possible to make the type condition more flexible in Awaited<T>
to enable these promise extensions and still have the type be compatible with Promise.all
, Promise.race
, etc?
Originally posted by @julienavert in #45350 (comment)