Skip to content

Commit a203ace

Browse files
Ban inferred return type on async and generator functions. (microsoft#58628)
1 parent ddf43cd commit a203ace

File tree

5 files changed

+134
-0
lines changed

5 files changed

+134
-0
lines changed

src/compiler/checker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -48984,6 +48984,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4898448984
function getSingleReturnExpression(declaration: SignatureDeclaration | undefined): Expression | undefined {
4898548985
let candidateExpr: Expression | undefined;
4898648986
if (declaration && !nodeIsMissing((declaration as FunctionLikeDeclaration).body)) {
48987+
if (getFunctionFlags(declaration) & FunctionFlags.AsyncGenerator) return undefined;
4898748988
const body = (declaration as FunctionLikeDeclaration).body;
4898848989
if (body && isBlock(body)) {
4898948990
forEachReturnStatement(body, s => {

src/compiler/expressionToTypeNode.ts

+4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import {
1414
Expression,
1515
forEachReturnStatement,
1616
FunctionExpression,
17+
FunctionFlags,
1718
FunctionLikeDeclaration,
1819
GetAccessorDeclaration,
1920
getEffectiveReturnTypeNode,
2021
getEffectiveTypeAnnotationNode,
22+
getFunctionFlags,
2123
getJSDocTypeAssertionType,
2224
getStrictOptionValue,
2325
HasInferredType,
@@ -469,6 +471,8 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
469471
function typeFromSingleReturnExpression(declaration: FunctionLikeDeclaration | undefined, context: SyntacticTypeNodeBuilderContext): boolean | undefined {
470472
let candidateExpr: Expression | undefined;
471473
if (declaration && !nodeIsMissing(declaration.body)) {
474+
if (getFunctionFlags(declaration) & FunctionFlags.AsyncGenerator) return undefined;
475+
472476
const body = declaration.body;
473477
if (body && isBlock(body)) {
474478
forEachReturnStatement(body, s => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [declarationAsyncAndGeneratorFunctions.ts] ////
2+
export async function asyncFn() {
3+
return {} as Promise<void>
4+
}
5+
6+
export async function asyncFn2() {
7+
return {} as number
8+
}
9+
10+
export async function asyncFn3() {
11+
return (await 42) as number;
12+
}
13+
14+
export function* generatorFn() {
15+
return {} as number
16+
}
17+
18+
export async function* asyncGeneratorFn() {
19+
return {} as number
20+
}
21+
//// [declarationAsyncAndGeneratorFunctions.d.ts] ////
22+
export declare function asyncFn(): unknown;
23+
export declare function asyncFn2(): unknown;
24+
export declare function asyncFn3(): unknown;
25+
export declare function generatorFn(): {};
26+
export declare function asyncGeneratorFn(): {};
27+
28+
29+
//// [Diagnostics reported]
30+
declarationAsyncAndGeneratorFunctions.ts(1,23): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
31+
declarationAsyncAndGeneratorFunctions.ts(5,23): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
32+
declarationAsyncAndGeneratorFunctions.ts(9,23): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
33+
declarationAsyncAndGeneratorFunctions.ts(13,18): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
34+
declarationAsyncAndGeneratorFunctions.ts(17,24): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
35+
36+
37+
==== declarationAsyncAndGeneratorFunctions.ts (5 errors) ====
38+
export async function asyncFn() {
39+
~~~~~~~
40+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
41+
!!! related TS9031 declarationAsyncAndGeneratorFunctions.ts:1:23: Add a return type to the function declaration.
42+
return {} as Promise<void>
43+
}
44+
45+
export async function asyncFn2() {
46+
~~~~~~~~
47+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
48+
!!! related TS9031 declarationAsyncAndGeneratorFunctions.ts:5:23: Add a return type to the function declaration.
49+
return {} as number
50+
}
51+
52+
export async function asyncFn3() {
53+
~~~~~~~~
54+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
55+
!!! related TS9031 declarationAsyncAndGeneratorFunctions.ts:9:23: Add a return type to the function declaration.
56+
return (await 42) as number;
57+
}
58+
59+
export function* generatorFn() {
60+
~~~~~~~~~~~
61+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
62+
!!! related TS9031 declarationAsyncAndGeneratorFunctions.ts:13:18: Add a return type to the function declaration.
63+
return {} as number
64+
}
65+
66+
export async function* asyncGeneratorFn() {
67+
~~~~~~~~~~~~~~~~
68+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
69+
!!! related TS9031 declarationAsyncAndGeneratorFunctions.ts:17:24: Add a return type to the function declaration.
70+
return {} as number
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [declarationAsyncAndGeneratorFunctions.ts] ////
2+
export async function asyncFn() {
3+
return {} as Promise<void>
4+
}
5+
6+
export async function asyncFn2() {
7+
return {} as number
8+
}
9+
10+
export async function asyncFn3() {
11+
return (await 42) as number;
12+
}
13+
14+
export function* generatorFn() {
15+
return {} as number
16+
}
17+
18+
export async function* asyncGeneratorFn() {
19+
return {} as number
20+
}
21+
//// [declarationAsyncAndGeneratorFunctions.js] ////
22+
export async function asyncFn() {
23+
return {};
24+
}
25+
export async function asyncFn2() {
26+
return {};
27+
}
28+
export async function asyncFn3() {
29+
return (await 42);
30+
}
31+
export function* generatorFn() {
32+
return {};
33+
}
34+
export async function* asyncGeneratorFn() {
35+
return {};
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// @declaration: true
2+
// @target: esnext
3+
4+
export async function asyncFn() {
5+
return {} as Promise<void>
6+
}
7+
8+
export async function asyncFn2() {
9+
return {} as number
10+
}
11+
12+
export async function asyncFn3() {
13+
return (await 42) as number;
14+
}
15+
16+
export function* generatorFn() {
17+
return {} as number
18+
}
19+
20+
export async function* asyncGeneratorFn() {
21+
return {} as number
22+
}

0 commit comments

Comments
 (0)