Skip to content

Commit

Permalink
feat(eslint-plugin): [require-await] allow yielding Promise in async …
Browse files Browse the repository at this point in the history
…generators (#8003)

* feat(eslint-plugin): [require-await] allow yielding Promise in async generators

* chore: refactor `visitYieldExpression` a bit
  • Loading branch information
auvred committed Dec 5, 2023
1 parent 314f034 commit 4c3e704
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
21 changes: 15 additions & 6 deletions packages/eslint-plugin/src/rules/require-await.ts
Expand Up @@ -112,18 +112,27 @@ export default createRule({
}

/**
* mark `scopeInfo.isAsyncYield` to `true` if its a generator
* function and the delegate is `true`
* Mark `scopeInfo.isAsyncYield` to `true` if it
* 1) delegates async generator function
* or
* 2) yields thenable type
*/
function markAsHasDelegateGen(node: TSESTree.YieldExpression): void {
function visitYieldExpression(node: TSESTree.YieldExpression): void {
if (!scopeInfo?.isGen || !node.argument) {
return;
}

if (node.argument.type === AST_NODE_TYPES.Literal) {
// making this `false` as for literals we don't need to check the definition
// ignoring this as for literals we don't need to check the definition
// eg : async function* run() { yield* 1 }
scopeInfo.isAsyncYield ||= false;
return;
}

if (!node.delegate) {
if (isThenableType(services.esTreeNodeToTSNodeMap.get(node.argument))) {
scopeInfo.isAsyncYield = true;
}
return;
}

const type = services.getTypeAtLocation(node.argument);
Expand Down Expand Up @@ -152,7 +161,7 @@ export default createRule({
AwaitExpression: markAsHasAwait,
'VariableDeclaration[kind = "await using"]': markAsHasAwait,
'ForOfStatement[await = true]': markAsHasAwait,
'YieldExpression[delegate = true]': markAsHasDelegateGen,
YieldExpression: visitYieldExpression,

// check body-less async arrow function.
// ignore `async () => await foo` because it's obviously correct
Expand Down
24 changes: 24 additions & 0 deletions packages/eslint-plugin/tests/rules/require-await.test.ts
Expand Up @@ -237,6 +237,30 @@ async function* foo(): Promise<string> {
await using foo = new Bar();
};
`,
`
async function* test1() {
yield Promise.resolve(1);
}
`,
`
function asyncFunction() {
return Promise.resolve(1);
}
async function* test1() {
yield asyncFunction();
}
`,
`
declare const asyncFunction: () => Promise<void>;
async function* test1() {
yield asyncFunction();
}
`,
`
async function* test1() {
yield new Promise(() => {});
}
`,
],

invalid: [
Expand Down

0 comments on commit 4c3e704

Please sign in to comment.