Skip to content

Commit 4da470d

Browse files
authored
fix56509: return type if tryCreateAwaitedType fails (#58547)
1 parent 5c21b7f commit 4da470d

File tree

6 files changed

+302
-4
lines changed

6 files changed

+302
-4
lines changed

src/compiler/checker.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -41889,10 +41889,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4188941889
// - The base constraint of `T` is an object type with a callable `then` method.
4189041890

4189141891
if (isAwaitedTypeNeeded(type)) {
41892-
const awaitedType = tryCreateAwaitedType(type);
41893-
if (awaitedType) {
41894-
return awaitedType;
41895-
}
41892+
return tryCreateAwaitedType(type) ?? type;
4189641893
}
4189741894

4189841895
Debug.assert(isAwaitedTypeInstantiation(type) || getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like.");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
error TS2318: Cannot find global type 'Array'.
2+
error TS2318: Cannot find global type 'Awaited'.
3+
error TS2318: Cannot find global type 'Boolean'.
4+
error TS2318: Cannot find global type 'Function'.
5+
error TS2318: Cannot find global type 'IArguments'.
6+
error TS2318: Cannot find global type 'Number'.
7+
error TS2318: Cannot find global type 'Object'.
8+
error TS2318: Cannot find global type 'RegExp'.
9+
error TS2318: Cannot find global type 'String'.
10+
awaitedTypeNoLib.ts(3,15): error TS2304: Cannot find name 'PromiseLike'.
11+
awaitedTypeNoLib.ts(18,27): error TS2345: Argument of type 'NotPromise<TResult> | Thenable<NotPromise<TResult>>' is not assignable to parameter of type 'Thenable<TResult>'.
12+
Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
13+
Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
14+
Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
15+
Type 'unknown' is not assignable to type 'TResult'.
16+
'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
17+
18+
19+
!!! error TS2318: Cannot find global type 'Array'.
20+
!!! error TS2318: Cannot find global type 'Awaited'.
21+
!!! error TS2318: Cannot find global type 'Boolean'.
22+
!!! error TS2318: Cannot find global type 'Function'.
23+
!!! error TS2318: Cannot find global type 'IArguments'.
24+
!!! error TS2318: Cannot find global type 'Number'.
25+
!!! error TS2318: Cannot find global type 'Object'.
26+
!!! error TS2318: Cannot find global type 'RegExp'.
27+
!!! error TS2318: Cannot find global type 'String'.
28+
==== awaitedTypeNoLib.ts (2 errors) ====
29+
type NotPromise<T> = T extends Thenable<unknown>
30+
? T
31+
: T extends PromiseLike<unknown>
32+
~~~~~~~~~~~
33+
!!! error TS2304: Cannot find name 'PromiseLike'.
34+
? never
35+
: T;
36+
37+
type Receiver<T> = (value: NotPromise<T>) => void;
38+
39+
class Thenable<T> {
40+
then(a: Receiver<T>) {}
41+
42+
private handleResolve<TResult>(
43+
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
44+
resolve: Receiver<TResult>,
45+
) {
46+
if (result instanceof Thenable) {
47+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
48+
this.resolvePromise(result, resolve);
49+
~~~~~~
50+
!!! error TS2345: Argument of type 'NotPromise<TResult> | Thenable<NotPromise<TResult>>' is not assignable to parameter of type 'Thenable<TResult>'.
51+
!!! error TS2345: Type 'NotPromise<TResult>' is not assignable to type 'Thenable<TResult>'.
52+
!!! error TS2345: Type 'TResult | (TResult extends PromiseLike<unknown> ? never : TResult)' is not assignable to type 'Thenable<TResult>'.
53+
!!! error TS2345: Type 'Thenable<unknown> & TResult' is not assignable to type 'Thenable<TResult>'.
54+
!!! error TS2345: Type 'unknown' is not assignable to type 'TResult'.
55+
!!! error TS2345: 'TResult' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
56+
}
57+
}
58+
59+
private resolvePromise<TResult>(
60+
result: Thenable<TResult>,
61+
resolve: Receiver<TResult>,
62+
) {}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
2+
3+
//// [awaitedTypeNoLib.ts]
4+
type NotPromise<T> = T extends Thenable<unknown>
5+
? T
6+
: T extends PromiseLike<unknown>
7+
? never
8+
: T;
9+
10+
type Receiver<T> = (value: NotPromise<T>) => void;
11+
12+
class Thenable<T> {
13+
then(a: Receiver<T>) {}
14+
15+
private handleResolve<TResult>(
16+
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
17+
resolve: Receiver<TResult>,
18+
) {
19+
if (result instanceof Thenable) {
20+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
21+
this.resolvePromise(result, resolve);
22+
}
23+
}
24+
25+
private resolvePromise<TResult>(
26+
result: Thenable<TResult>,
27+
resolve: Receiver<TResult>,
28+
) {}
29+
}
30+
31+
//// [awaitedTypeNoLib.js]
32+
var Thenable = /** @class */ (function () {
33+
function Thenable() {
34+
}
35+
Thenable.prototype.then = function (a) { };
36+
Thenable.prototype.handleResolve = function (result, resolve) {
37+
if (result instanceof Thenable) {
38+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
39+
this.resolvePromise(result, resolve);
40+
}
41+
};
42+
Thenable.prototype.resolvePromise = function (result, resolve) { };
43+
return Thenable;
44+
}());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
2+
3+
=== awaitedTypeNoLib.ts ===
4+
type NotPromise<T> = T extends Thenable<unknown>
5+
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
6+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
7+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
8+
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
9+
10+
? T
11+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
12+
13+
: T extends PromiseLike<unknown>
14+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
15+
>PromiseLike : Symbol(PromiseLike)
16+
17+
? never
18+
: T;
19+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 0, 16))
20+
21+
type Receiver<T> = (value: NotPromise<T>) => void;
22+
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
23+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 6, 14))
24+
>value : Symbol(value, Decl(awaitedTypeNoLib.ts, 6, 20))
25+
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
26+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 6, 14))
27+
28+
class Thenable<T> {
29+
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
30+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 8, 15))
31+
32+
then(a: Receiver<T>) {}
33+
>then : Symbol(Thenable.then, Decl(awaitedTypeNoLib.ts, 8, 19))
34+
>a : Symbol(a, Decl(awaitedTypeNoLib.ts, 9, 7))
35+
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
36+
>T : Symbol(T, Decl(awaitedTypeNoLib.ts, 8, 15))
37+
38+
private handleResolve<TResult>(
39+
>handleResolve : Symbol(Thenable.handleResolve, Decl(awaitedTypeNoLib.ts, 9, 25))
40+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
41+
42+
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
43+
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
44+
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
45+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
46+
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
47+
>NotPromise : Symbol(NotPromise, Decl(awaitedTypeNoLib.ts, 0, 0))
48+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
49+
50+
resolve: Receiver<TResult>,
51+
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 12, 64))
52+
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
53+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 11, 24))
54+
55+
) {
56+
if (result instanceof Thenable) {
57+
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
58+
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
59+
60+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
61+
this.resolvePromise(result, resolve);
62+
>this.resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
63+
>this : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
64+
>resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
65+
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 11, 33))
66+
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 12, 64))
67+
}
68+
}
69+
70+
private resolvePromise<TResult>(
71+
>resolvePromise : Symbol(Thenable.resolvePromise, Decl(awaitedTypeNoLib.ts, 19, 3))
72+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
73+
74+
result: Thenable<TResult>,
75+
>result : Symbol(result, Decl(awaitedTypeNoLib.ts, 21, 34))
76+
>Thenable : Symbol(Thenable, Decl(awaitedTypeNoLib.ts, 6, 50))
77+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
78+
79+
resolve: Receiver<TResult>,
80+
>resolve : Symbol(resolve, Decl(awaitedTypeNoLib.ts, 22, 30))
81+
>Receiver : Symbol(Receiver, Decl(awaitedTypeNoLib.ts, 4, 6))
82+
>TResult : Symbol(TResult, Decl(awaitedTypeNoLib.ts, 21, 25))
83+
84+
) {}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//// [tests/cases/compiler/awaitedTypeNoLib.ts] ////
2+
3+
=== awaitedTypeNoLib.ts ===
4+
type NotPromise<T> = T extends Thenable<unknown>
5+
>NotPromise : NotPromise<T>
6+
> : ^^^^^^^^^^^^^
7+
8+
? T
9+
: T extends PromiseLike<unknown>
10+
? never
11+
: T;
12+
13+
type Receiver<T> = (value: NotPromise<T>) => void;
14+
>Receiver : Receiver<T>
15+
> : ^^^^^^^^^^^
16+
>value : NotPromise<T>
17+
> : ^^^^^^^^^^^^^
18+
19+
class Thenable<T> {
20+
>Thenable : Thenable<T>
21+
> : ^^^^^^^^^^^
22+
23+
then(a: Receiver<T>) {}
24+
>then : (a: Receiver<T>) => void
25+
> : ^ ^^ ^^^^^^^^^
26+
>a : Receiver<T>
27+
> : ^^^^^^^^^^^
28+
29+
private handleResolve<TResult>(
30+
>handleResolve : <TResult>(result: NotPromise<TResult> | Thenable<NotPromise<TResult>>, resolve: Receiver<TResult>) => void
31+
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
32+
33+
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
34+
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
35+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
37+
resolve: Receiver<TResult>,
38+
>resolve : Receiver<TResult>
39+
> : ^^^^^^^^^^^^^^^^^
40+
41+
) {
42+
if (result instanceof Thenable) {
43+
>result instanceof Thenable : boolean
44+
> : ^^^^^^^
45+
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
46+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47+
>Thenable : typeof Thenable
48+
> : ^^^^^^^^^^^^^^^
49+
50+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
51+
this.resolvePromise(result, resolve);
52+
>this.resolvePromise(result, resolve) : void
53+
> : ^^^^
54+
>this.resolvePromise : <TResult_1>(result: Thenable<TResult_1>, resolve: Receiver<TResult_1>) => void
55+
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
56+
>this : this
57+
> : ^^^^
58+
>resolvePromise : <TResult_1>(result: Thenable<TResult_1>, resolve: Receiver<TResult_1>) => void
59+
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
60+
>result : NotPromise<TResult> | Thenable<NotPromise<TResult>>
61+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62+
>resolve : Receiver<TResult>
63+
> : ^^^^^^^^^^^^^^^^^
64+
}
65+
}
66+
67+
private resolvePromise<TResult>(
68+
>resolvePromise : <TResult>(result: Thenable<TResult>, resolve: Receiver<TResult>) => void
69+
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^
70+
71+
result: Thenable<TResult>,
72+
>result : Thenable<TResult>
73+
> : ^^^^^^^^^^^^^^^^^
74+
75+
resolve: Receiver<TResult>,
76+
>resolve : Receiver<TResult>
77+
> : ^^^^^^^^^^^^^^^^^
78+
79+
) {}
80+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @strictFunctionTypes: true
2+
// @noLib: true
3+
4+
type NotPromise<T> = T extends Thenable<unknown>
5+
? T
6+
: T extends PromiseLike<unknown>
7+
? never
8+
: T;
9+
10+
type Receiver<T> = (value: NotPromise<T>) => void;
11+
12+
class Thenable<T> {
13+
then(a: Receiver<T>) {}
14+
15+
private handleResolve<TResult>(
16+
result: NotPromise<TResult> | Thenable<NotPromise<TResult>>,
17+
resolve: Receiver<TResult>,
18+
) {
19+
if (result instanceof Thenable) {
20+
// #58547 This previously was a Debug Failure. False expression: type provided should not be a non-generic 'promise'-like.
21+
this.resolvePromise(result, resolve);
22+
}
23+
}
24+
25+
private resolvePromise<TResult>(
26+
result: Thenable<TResult>,
27+
resolve: Receiver<TResult>,
28+
) {}
29+
}

0 commit comments

Comments
 (0)