Skip to content

Commit 56c00b3

Browse files
authored
fix(eslint-plugin): [req-await] crash on nonasync promise return (typescript-eslint#1228)
1 parent dd9f58c commit 56c00b3

File tree

3 files changed

+90
-112
lines changed

3 files changed

+90
-112
lines changed

packages/eslint-plugin/src/rules/require-await.ts

+8-11
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,26 @@ export default util.createRule<Options, MessageIds>({
4242
}
4343

4444
return {
45-
'FunctionDeclaration[async = true]': rules.FunctionDeclaration,
46-
'FunctionExpression[async = true]': rules.FunctionExpression,
45+
FunctionDeclaration: rules.FunctionDeclaration,
46+
FunctionExpression: rules.FunctionExpression,
47+
ArrowFunctionExpression: rules.ArrowFunctionExpression,
4748
'ArrowFunctionExpression[async = true]'(
4849
node: TSESTree.ArrowFunctionExpression,
4950
): void {
50-
rules.ArrowFunctionExpression(node);
51-
5251
// If body type is not BlockStatment, we need to check the return type here
5352
if (node.body.type !== AST_NODE_TYPES.BlockStatement) {
5453
const expression = parserServices.esTreeNodeToTSNodeMap.get(
5554
node.body,
5655
);
5756
if (expression && isThenableType(expression)) {
5857
// tell the base rule to mark the scope as having an await so it ignores it
59-
rules.AwaitExpression(node as never);
58+
rules.AwaitExpression();
6059
}
6160
}
6261
},
63-
'FunctionDeclaration[async = true]:exit':
64-
rules['FunctionDeclaration:exit'],
65-
'FunctionExpression[async = true]:exit': rules['FunctionExpression:exit'],
66-
'ArrowFunctionExpression[async = true]:exit':
67-
rules['ArrowFunctionExpression:exit'],
62+
'FunctionDeclaration:exit': rules['FunctionDeclaration:exit'],
63+
'FunctionExpression:exit': rules['FunctionExpression:exit'],
64+
'ArrowFunctionExpression:exit': rules['ArrowFunctionExpression:exit'],
6865
AwaitExpression: rules.AwaitExpression,
6966
ForOfStatement: rules.ForOfStatement,
7067

@@ -74,7 +71,7 @@ export default util.createRule<Options, MessageIds>({
7471
>(node);
7572
if (expression && isThenableType(expression)) {
7673
// tell the base rule to mark the scope as having an await so it ignores it
77-
rules.AwaitExpression(node as never);
74+
rules.AwaitExpression();
7875
}
7976
},
8077
};

packages/eslint-plugin/tests/rules/require-await.test.ts

+81-100
Original file line numberDiff line numberDiff line change
@@ -28,106 +28,87 @@ const noAwaitAsyncFunctionExpression: any = {
2828

2929
ruleTester.run('require-await', rule, {
3030
valid: [
31-
{
32-
// Non-async function declaration
33-
code: `function numberOne(): number {
34-
return 1;
35-
}`,
36-
},
37-
{
38-
// Non-async function expression
39-
code: `const numberOne = function(): number {
40-
return 1;
41-
}`,
42-
},
43-
{
44-
// Non-async arrow function expression (concise-body)
45-
code: `const numberOne = (): number => 1;`,
46-
},
47-
{
48-
// Non-async arrow function expression (block-body)
49-
code: `const numberOne = (): number => {
50-
return 1;
51-
};`,
52-
},
53-
{
54-
// Async function declaration with await
55-
code: `async function numberOne(): Promise<number> {
56-
return await 1;
57-
}`,
58-
},
59-
{
60-
// Async function expression with await
61-
code: `const numberOne = async function(): Promise<number> {
62-
return await 1;
63-
}`,
64-
},
65-
{
66-
// Async arrow function expression with await (concise-body)
67-
code: `const numberOne = async (): Promise<number> => await 1;`,
68-
},
69-
{
70-
// Async arrow function expression with await (block-body)
71-
code: `const numberOne = async (): Promise<number> => {
72-
return await 1;
73-
};`,
74-
},
75-
{
76-
// Async function declaration with promise return
77-
code: `async function numberOne(): Promise<number> {
78-
return Promise.resolve(1);
79-
}`,
80-
},
81-
{
82-
// Async function expression with promise return
83-
code: `const numberOne = async function(): Promise<number> {
84-
return Promise.resolve(1);
85-
}`,
86-
},
87-
{
88-
// Async arrow function with promise return (concise-body)
89-
code: `const numberOne = async (): Promise<number> => Promise.resolve(1);`,
90-
},
91-
{
92-
// Async arrow function with promise return (block-body)
93-
code: `const numberOne = async (): Promise<number> => {
94-
return Promise.resolve(1);
95-
};`,
96-
},
97-
{
98-
// Async function declaration with async function return
99-
code: `async function numberOne(): Promise<number> {
100-
return getAsyncNumber(1);
101-
}
102-
async function getAsyncNumber(x: number): Promise<number> {
103-
return Promise.resolve(x);
104-
}`,
105-
},
106-
{
107-
// Async function expression with async function return
108-
code: `const numberOne = async function(): Promise<number> {
109-
return getAsyncNumber(1);
110-
}
111-
const getAsyncNumber = async function(x: number): Promise<number> {
112-
return Promise.resolve(x);
113-
}`,
114-
},
115-
{
116-
// Async arrow function with async function return (concise-body)
117-
code: `const numberOne = async (): Promise<number> => getAsyncNumber(1);
118-
const getAsyncNumber = async function(x: number): Promise<number> {
119-
return Promise.resolve(x);
120-
}`,
121-
},
122-
{
123-
// Async arrow function with async function return (block-body)
124-
code: `const numberOne = async (): Promise<number> => {
125-
return getAsyncNumber(1);
126-
};
127-
const getAsyncNumber = async function(x: number): Promise<number> {
128-
return Promise.resolve(x);
129-
}`,
130-
},
31+
// Non-async function declaration
32+
`function numberOne(): number {
33+
return 1;
34+
}`,
35+
// Non-async function expression
36+
`const numberOne = function(): number {
37+
return 1;
38+
}`,
39+
// Non-async arrow function expression (concise-body)
40+
`const numberOne = (): number => 1;`,
41+
// Non-async arrow function expression (block-body)
42+
`const numberOne = (): number => {
43+
return 1;
44+
};`,
45+
// Non-async function that returns a promise
46+
// https://github.com/typescript-eslint/typescript-eslint/issues/1226
47+
`
48+
function delay() {
49+
return Promise.resolve();
50+
}
51+
`,
52+
`
53+
const delay = () => {
54+
return Promise.resolve();
55+
}
56+
`,
57+
`const delay = () => Promise.resolve();`,
58+
// Async function declaration with await
59+
`async function numberOne(): Promise<number> {
60+
return await 1;
61+
}`,
62+
// Async function expression with await
63+
`const numberOne = async function(): Promise<number> {
64+
return await 1;
65+
}`,
66+
// Async arrow function expression with await (concise-body)
67+
`const numberOne = async (): Promise<number> => await 1;`,
68+
// Async arrow function expression with await (block-body)
69+
`const numberOne = async (): Promise<number> => {
70+
return await 1;
71+
};`,
72+
// Async function declaration with promise return
73+
`async function numberOne(): Promise<number> {
74+
return Promise.resolve(1);
75+
}`,
76+
// Async function expression with promise return
77+
`const numberOne = async function(): Promise<number> {
78+
return Promise.resolve(1);
79+
}`,
80+
// Async arrow function with promise return (concise-body)
81+
`const numberOne = async (): Promise<number> => Promise.resolve(1);`,
82+
// Async arrow function with promise return (block-body)
83+
`const numberOne = async (): Promise<number> => {
84+
return Promise.resolve(1);
85+
};`,
86+
// Async function declaration with async function return
87+
`async function numberOne(): Promise<number> {
88+
return getAsyncNumber(1);
89+
}
90+
async function getAsyncNumber(x: number): Promise<number> {
91+
return Promise.resolve(x);
92+
}`,
93+
// Async function expression with async function return
94+
`const numberOne = async function(): Promise<number> {
95+
return getAsyncNumber(1);
96+
}
97+
const getAsyncNumber = async function(x: number): Promise<number> {
98+
return Promise.resolve(x);
99+
}`,
100+
// Async arrow function with async function return (concise-body)
101+
`const numberOne = async (): Promise<number> => getAsyncNumber(1);
102+
const getAsyncNumber = async function(x: number): Promise<number> {
103+
return Promise.resolve(x);
104+
}`,
105+
// Async arrow function with async function return (block-body)
106+
`const numberOne = async (): Promise<number> => {
107+
return getAsyncNumber(1);
108+
};
109+
const getAsyncNumber = async function(x: number): Promise<number> {
110+
return Promise.resolve(x);
111+
}`,
131112
// https://github.com/typescript-eslint/typescript-eslint/issues/1188
132113
`
133114
async function testFunction(): Promise<void> {

packages/eslint-plugin/typings/eslint-rules.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ declare module 'eslint/lib/rules/require-await' {
451451
node: TSESTree.ArrowFunctionExpression,
452452
): void;
453453
ReturnStatement(node: TSESTree.ReturnStatement): void;
454-
AwaitExpression(node: TSESTree.AwaitExpression): void;
454+
AwaitExpression(): void;
455455
ForOfStatement(node: TSESTree.ForOfStatement): void;
456456
}
457457
>;

0 commit comments

Comments
 (0)