fix56509: return type if tryCreateAwaitedType fails (#58547)

This commit is contained in:
Isabel Duan 2024-05-16 14:02:15 -07:00 committed by GitHub
parent 5c21b7fd93
commit 4da470da37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 302 additions and 4 deletions

View File

@ -41889,10 +41889,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// - The base constraint of `T` is an object type with a callable `then` method.
if (isAwaitedTypeNeeded(type)) {
const awaitedType = tryCreateAwaitedType(type);
if (awaitedType) {
return awaitedType;
}
return tryCreateAwaitedType(type) ?? type;
}
Debug.assert(isAwaitedTypeInstantiation(type) || getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like.");

View File

@ -0,0 +1,63 @@
error TS2318: Cannot find global type 'Array'.
error TS2318: Cannot find global type 'Awaited'.
error TS2318: Cannot find global type 'Boolean'.
error TS2318: Cannot find global type 'Function'.
error TS2318: Cannot find global type 'IArguments'.
error TS2318: Cannot find global type 'Number'.
error TS2318: Cannot find global type 'Object'.
error TS2318: Cannot find global type 'RegExp'.
error TS2318: Cannot find global type 'String'.
awaitedTypeNoLib.ts(3,15): error TS2304: Cannot find name 'PromiseLike'.
awaitedTypeNoLib.ts(18,27): error TS2345: Argument of type 'NotPromise<TResult> | Thenable<NotPromise<TResult>>' is not assignable to parameter of type 'Thenable<TResult>'.
Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
Type 'unknown' is not assignable to type 'TResult'.
'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
!!! error TS2318: Cannot find global type 'Array'.
!!! error TS2318: Cannot find global type 'Awaited'.
!!! error TS2318: Cannot find global type 'Boolean'.
!!! error TS2318: Cannot find global type 'Function'.
!!! error TS2318: Cannot find global type 'IArguments'.
!!! error TS2318: Cannot find global type 'Number'.
!!! error TS2318: Cannot find global type 'Object'.
!!! error TS2318: Cannot find global type 'RegExp'.
!!! error TS2318: Cannot find global type 'String'.
==== awaitedTypeNoLib.ts (2 errors) ====
type NotPromise<T> = T extends Thenable<unknown>
? T
: T extends PromiseLike<unknown>
~~~~~~~~~~~
!!! error TS2304: Cannot find name 'PromiseLike'.
? never
: T;
type Receiver<T> = (value: NotPromise<T>) => void;
class Thenable<T> {
then(a: Receiver<T>) {}
private handleResolve<TResult>(
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
resolve: Receiver<TResult>,
) {
if (result instanceof Thenable) {
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
~~~~~~
!!! error TS2345: Argument of type 'NotPromise<TResult> | Thenable<NotPromise<TResult>>' is not assignable to parameter of type 'Thenable<TResult>'.
!!! error TS2345: Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
!!! error TS2345: Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
!!! error TS2345: Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
!!! error TS2345: Type 'unknown' is not assignable to type 'TResult'.
!!! error TS2345: 'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
}
}
private resolvePromise<TResult>(
result: Thenable<TResult>,
resolve: Receiver<TResult>,
) {}
}

View File

@ -0,0 +1,44 @@
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
//// [awaitedTypeNoLib.ts]
type NotPromise<T> = T extends Thenable<unknown>
? T
: T extends PromiseLike<unknown>
? never
: T;
type Receiver<T> = (value: NotPromise<T>) => void;
class Thenable<T> {
then(a: Receiver<T>) {}
private handleResolve<TResult>(
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
resolve: Receiver<TResult>,
) {
if (result instanceof Thenable) {
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
}
}
private resolvePromise<TResult>(
result: Thenable<TResult>,
resolve: Receiver<TResult>,
) {}
}
//// [awaitedTypeNoLib.js]
var Thenable = /** @class */ (function () {
function Thenable() {
}
Thenable.prototype.then = function (a) { };
Thenable.prototype.handleResolve = function (result, resolve) {
if (result instanceof Thenable) {
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
}
};
Thenable.prototype.resolvePromise = function (result, resolve) { };
return Thenable;
}());

View File

@ -0,0 +1,85 @@
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
=== awaitedTypeNoLib.ts ===
type NotPromise<T> = T extends Thenable<unknown>
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
? T
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
: T extends PromiseLike<unknown>
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
>PromiseLike : Symbol(PromiseLike)
? never
: T;
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
type Receiver<T> = (value: NotPromise<T>) => void;
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 6, 14))
>value : Symbol(value, Decl(awaitedTypeNoLib.ts, 6, 20))
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 6, 14))
class Thenable<T> {
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 8, 15))
then(a: Receiver<T>) {}
>then : Symbol(Thenable.then, Decl(awaitedTypeNoLib.ts, 8, 19))
>a : Symbol(a, Decl(awaitedTypeNoLib.ts, 9, 7))
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 8, 15))
private handleResolve<TResult>(
>handleResolve : Symbol(Thenable.handleResolve, Decl(awaitedTypeNoLib.ts, 9, 25))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
resolve: Receiver<TResult>,
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 12, 64))
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
) {
if (result instanceof Thenable) {
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
>this.resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
>this : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
>resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 12, 64))
}
}
private resolvePromise<TResult>(
>resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
result: Thenable<TResult>,
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 21, 34))
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
resolve: Receiver<TResult>,
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 22, 30))
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
) {}
}

View File

@ -0,0 +1,80 @@
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
=== awaitedTypeNoLib.ts ===
type NotPromise<T> = T extends Thenable<unknown>
>NotPromise : NotPromise<T>
> : ^^^^^^^^^^^^^
? T
: T extends PromiseLike<unknown>
? never
: T;
type Receiver<T> = (value: NotPromise<T>) => void;
>Receiver : Receiver<T>
> : ^^^^^^^^^^^
>value : NotPromise<T>
> : ^^^^^^^^^^^^^
class Thenable<T> {
>Thenable : Thenable<T>
> : ^^^^^^^^^^^
then(a: Receiver<T>) {}
>then : (a: Receiver<T>) => void
> : ^ ^^ ^^^^^^^^^
>a : Receiver<T>
> : ^^^^^^^^^^^
private handleResolve<TResult>(
>handleResolve : <TResult>(result: NotPromise<TResult> | Thenable<NotPromise<TResult>>, resolve: Receiver<TResult>) => void
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
resolve: Receiver<TResult>,
>resolve : Receiver<TResult>
> : ^^^^^^^^^^^^^^^^^
) {
if (result instanceof Thenable) {
>result instanceof Thenable : boolean
> : ^^^^^^^
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Thenable : typeof Thenable
> : ^^^^^^^^^^^^^^^
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
>this.resolvePromise(result, resolve) : void
> : ^^^^
>this.resolvePromise : <TResult_1>(result: Thenable<TResult_1>, resolve: Receiver<TResult_1>) => void
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
>this : this
> : ^^^^
>resolvePromise : <TResult_1>(result: Thenable<TResult_1>, resolve: Receiver<TResult_1>) => void
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>resolve : Receiver<TResult>
> : ^^^^^^^^^^^^^^^^^
}
}
private resolvePromise<TResult>(
>resolvePromise : <TResult>(result: Thenable<TResult>, resolve: Receiver<TResult>) => void
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
result: Thenable<TResult>,
>result : Thenable<TResult>
> : ^^^^^^^^^^^^^^^^^
resolve: Receiver<TResult>,
>resolve : Receiver<TResult>
> : ^^^^^^^^^^^^^^^^^
) {}
}

View File

@ -0,0 +1,29 @@
// @strictFunctionTypes: true
// @noLib: true
type NotPromise<T> = T extends Thenable<unknown>
? T
: T extends PromiseLike<unknown>
? never
: T;
type Receiver<T> = (value: NotPromise<T>) => void;
class Thenable<T> {
then(a: Receiver<T>) {}
private handleResolve<TResult>(
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
resolve: Receiver<TResult>,
) {
if (result instanceof Thenable) {
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
this.resolvePromise(result, resolve);
}
}
private resolvePromise<TResult>(
result: Thenable<TResult>,
resolve: Receiver<TResult>,
) {}
}