Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[eslint] Enhance Rule.NodeListener type #45821

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion types/eslint/ts3.1/eslint-tests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Comment } from 'estree';
import { Comment, WhileStatement } from 'estree';
import { AST, SourceCode, Rule, Linter, ESLint, CLIEngine, RuleTester, Scope } from 'eslint';

const SOURCE = `var foo = bar;`;
Expand Down Expand Up @@ -381,6 +381,7 @@ rule = {
onCodePathSegmentEnd(segment, node) {},
onCodePathSegmentLoop(fromSegment, toSegment, node) {},
IfStatement(node) {},
WhileStatement(node: WhileStatement) {},
'Program:exit'() {},
};
},
Expand Down
9 changes: 8 additions & 1 deletion types/eslint/ts3.1/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,13 @@ export namespace Rule {
}

type NodeTypes = ESTree.Node['type'];
type NodeListener = { [T in NodeTypes]?: (node: ESTree.Node) => void };
type NodeListener = ESTree.Node extends infer T
? (T extends ESTree.Node ? (_: { [_ in T['type']]?: (node: T) => void }) => void : never) extends (
_: infer U,
) => void
? U
: never
: never;
Copy link
Contributor

@bradzacher bradzacher Jul 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this kind of conditional logic is a good idea
In my experience, creating types dynamically like this over large sets (ESTree.Node is a union of 70 interfaces with 68 distinct type's) can easily cause OOMs in TS
microsoft/TypeScript#30473

This is evidenced by the above typescript-bot perf check which lists the memory usage as being 25% higher.

When I dumped this into a local repo, vscode's typescript integration paused for a few seconds whilst it computed the types.

The only thing that I've found to work efficiently is to list out every single key manually:
https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/experimental-utils/src/ts-eslint/Rule.ts#L247-L424


interface RuleListener extends NodeListener {
onCodePathStart?(codePath: CodePath, node: ESTree.Node): void;
Expand All @@ -254,6 +260,7 @@ export namespace Rule {
| ((segment: CodePathSegment, node: ESTree.Node) => void)
| ((fromSegment: CodePathSegment, toSegment: CodePathSegment, node: ESTree.Node) => void)
| ((node: ESTree.Node) => void)
| NodeListener[keyof NodeListener]
| undefined;
}

Expand Down