Skip to content

Commit 63adc5f

Browse files
committed
Add contextual typing for await operand
1 parent 80dba4d commit 63adc5f

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16409,6 +16409,15 @@ namespace ts {
1640916409
return undefined;
1641016410
}
1641116411

16412+
function getContextualTypeForAwaitOperand(node: AwaitExpression): Type | undefined {
16413+
const contextualType = getContextualType(node);
16414+
if (contextualType) {
16415+
const contextualAwaitedType = getAwaitedType(contextualType);
16416+
return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
16417+
}
16418+
return undefined;
16419+
}
16420+
1641216421
function getContextualTypeForYieldOperand(node: YieldExpression): Type | undefined {
1641316422
const func = getContainingFunction(node);
1641416423
if (func) {
@@ -16770,7 +16779,9 @@ namespace ts {
1677016779
return getContextualTypeForReturnExpression(node);
1677116780
case SyntaxKind.YieldExpression:
1677216781
return getContextualTypeForYieldOperand(<YieldExpression>parent);
16773-
case SyntaxKind.CallExpression:
16782+
case SyntaxKind.AwaitExpression:
16783+
return getContextualTypeForAwaitOperand(<AwaitExpression>parent);
16784+
case SyntaxKind.CallExpression:
1677416785
case SyntaxKind.NewExpression:
1677516786
return getContextualTypeForArgument(<CallExpression | NewExpression>parent, node);
1677616787
case SyntaxKind.TypeAssertionExpression:

tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.symbols

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,28 @@ async function fn2(): Promise<Obj> {
2727

2828
});
2929
}
30+
31+
async function fn3(): Promise<Obj> {
32+
>fn3 : Symbol(fn3, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 10, 1))
33+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
34+
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
35+
36+
return await { key: "value" };
37+
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 13, 18))
38+
}
39+
40+
async function fn4(): Promise<Obj> {
41+
>fn4 : Symbol(fn4, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 14, 1))
42+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
43+
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
44+
45+
return await new Promise(resolve => {
46+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
47+
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 17, 29))
48+
49+
resolve({ key: "value" });
50+
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 17, 29))
51+
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 18, 17))
52+
53+
});
54+
}

tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,33 @@ async function fn2(): Promise<Obj> {
2929

3030
});
3131
}
32+
33+
async function fn3(): Promise<Obj> {
34+
>fn3 : () => Promise<Obj>
35+
36+
return await { key: "value" };
37+
>await { key: "value" } : { key: "value"; }
38+
>{ key: "value" } : { key: "value"; }
39+
>key : "value"
40+
>"value" : "value"
41+
}
42+
43+
async function fn4(): Promise<Obj> {
44+
>fn4 : () => Promise<Obj>
45+
46+
return await new Promise(resolve => {
47+
>await new Promise(resolve => { resolve({ key: "value" }); }) : Obj
48+
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
49+
>Promise : PromiseConstructor
50+
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
51+
>resolve : (value?: Obj | PromiseLike<Obj>) => void
52+
53+
resolve({ key: "value" });
54+
>resolve({ key: "value" }) : void
55+
>resolve : (value?: Obj | PromiseLike<Obj>) => void
56+
>{ key: "value" } : { key: "value"; }
57+
>key : "value"
58+
>"value" : "value"
59+
60+
});
61+
}

tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnType.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,14 @@ async function fn2(): Promise<Obj> {
1212
return new Promise(resolve => {
1313
resolve({ key: "value" });
1414
});
15+
}
16+
17+
async function fn3(): Promise<Obj> {
18+
return await { key: "value" };
19+
}
20+
21+
async function fn4(): Promise<Obj> {
22+
return await new Promise(resolve => {
23+
resolve({ key: "value" });
24+
});
1525
}

0 commit comments

Comments
 (0)