- Notifications
You must be signed in to change notification settings - Fork30.5k
@types/eslint allow non-ESTree AST for parsers in flat configs#68232
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
@types/eslint allow non-ESTree AST for parsers in flat configs#68232
Uh oh!
There was an error while loading.Please reload this page.
Conversation
typescript-bot commentedJan 17, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@Logicer16 Thank you for submitting this PR! I see this is your first time submitting to DefinitelyTyped 👋 — I'm the local bot who will help you through the process of getting things through. This is a live comment which I will keep updated. 1 package in this PR
Code ReviewsBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged. You can test the changes of this PRin the Playground. Status
All of the items on the list are green.To merge, you need to post a comment including the string "Ready to merge" to bring in your changes. Diagnostic Information: What the bot saw about this PR{"type":"info","now":"-","pr_number":68232,"author":"Logicer16","headCommitOid":"e1705c2b53455f39aadcb291540fb2b05ea5e0e4","mergeBaseOid":"eb3890d3f5d74638cc97e862a273cf94b5bfca71","lastPushDate":"2024-01-17T11:24:14.000Z","lastActivityDate":"2024-02-27T20:04:27.000Z","mergeOfferDate":"2024-02-27T16:31:54.000Z","mergeRequestDate":"2024-02-27T20:04:27.000Z","mergeRequestUser":"Logicer16","hasMergeConflict":false,"isFirstContribution":true,"tooManyFiles":false,"hugeChange":false,"popularityLevel":"Critical","pkgInfo": [ {"name":"eslint","kind":"edit","files": [ {"path":"types/eslint/index.d.ts","kind":"definition" } ],"owners": ["pmdartus","j-f1","saadq","JasonHK","bradzacher","JounQin" ],"addedOwners": [],"deletedOwners": [],"popularityLevel":"Critical" } ],"reviews": [ {"type":"approved","reviewer":"jakebailey","date":"2024-02-27T16:31:13.000Z","isMaintainer":true }, {"type":"approved","reviewer":"JounQin","date":"2024-02-27T05:25:43.000Z","isMaintainer":false }, {"type":"approved","reviewer":"bradzacher","date":"2024-02-26T20:40:31.000Z","isMaintainer":false }, {"type":"stale","reviewer":"JoshuaKGoldberg","date":"2024-01-21T16:16:25.000Z","abbrOid":"363e1f5" } ],"mainBotCommentID":1895612488,"ciResult":"pass"} |
typescript-bot commentedJan 17, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
🔔@pmdartus@j-f1@saadq@JasonHK@bradzacher@JounQin — pleasereview this PR in the next few days. Be sure to explicitly select |
bradzacher left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm not quite sure I understand here - what's the motivation behind this?
Your PR description contains very little context.
Could you please provide more context and examples of real-world usecases that would be improved or enabled by this?
There's a whole lot of complexity being introduced here and it would be good to have a clear picture of why we'd add this complexity so we can determine if we're accepting the appropriate trade-offs.
typescript-bot commentedJan 17, 2024
@Logicer16 One or more reviewers has requested changes. Please address their comments. I'll be back once they sign off or you've pushed new commits. Thank you! |
a5deca8 toa4e5203Comparemostpinkest commentedJan 17, 2024
@bradzacher Sorry, should've explained myself before I submitted the pr. 😅 I've updated the description to include an explanation. Let me know if anything is unclear. |
typescript-bot commentedJan 17, 2024
@bradzacher Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
bradzacher commentedJan 17, 2024
Sorry, to clarify - I understand what you've done here. Instead I'm seeking to understand the why - what are the clear and real usecase examples that are currently broken and that this change fixes.
Most eslint parsers don't provide TS types I thought - do you have an example?
Do you have an example config that's not currently working? If your example is@typescript-eslint - I would counter with the project not supporting flat configs yet (reftypescript-eslint/typescript-eslint#7935). |
mostpinkest commentedJan 18, 2024
Of the 10 popular parsers I've sampled, all but
Test Configimport{Linter}from"eslint";importhtmlParserfrom"@html-eslint/parser";importmdxParserfrom"eslint-mdx";import*asgraphQLParserfrom"@graphql-eslint/eslint-plugin";importyamlParserfrom"yaml-eslint-parser";importtomlParserfrom"toml-eslint-parser";importjsonParserfrom"jsonc-eslint-parser";importastroParserfrom"astro-eslint-parser";importvueParserfrom"vue-eslint-parser";importsvelteParserfrom"svelte-eslint-parser";importtypescriptParserfrom"@typescript-eslint/parser"exportconstmyConfig:Linter.FlatConfig[]=[{languageOptions:{parser:htmlParser}},{languageOptions:{parser:svelteParser}},{languageOptions:{parser:mdxParser}},{languageOptions:{parser:graphQLParser}},{languageOptions:{parser:yamlParser}},{languageOptions:{parser:jsonParser}},{languageOptions:{parser:tomlParser}},{languageOptions:{parser:astroParser}},{languageOptions:{parser:vueParser}},{languageOptions:{parser:typescriptParser}}];
While yes, they don't yet support flat configs, flat configs have an identical parser api to the legacy config format. As long as the parser already implemented the correct interfaces, no changes need to be made for them to support the new format. This is evident in the pr you referenced. Regardless, 6 other parsers still experience this issue. During my testing, I've also fixed some related issues which also prevent other ASTs:
*With |
fbd4b70 to4153f49Comparebradzacher commentedJan 18, 2024
My big question would be - why validate the parser shape at all? By allowing non-estree-typed parsers you're introducing an explicit tear into the types - some of the APIs across the eskijt types accept estree nodes, some accept more generic ones. Others are expliclty typed to return estree nodes too - which is where the bigger tear is. Instead of making some of the surface area generic - why not just make the config itself more generic - eg enforce the rough shape of a parser for validation reasons but leave the specifics untyped (eg like That way the API surface area of each parser and plugin can remain typed in whatever way they want or need and the configs can enforce you pass something parser-like and we limit the surface area of the change to just the place that needs it. |
mostpinkest commentedJan 18, 2024
The unique thing about ESTree nodes is that up until the point their Also, the nodes being passed to and returned from the API are the same nodes returned by the parser. If a custom parser is being used and that parser provides non-ESTree nodes, those will be the ones passed to and returned from those functions. This change reflects that aspect of the API.
This is certainly a possibility that I hadn't considered. While this would work, you'd sacrifice the guarantee that the parser is the correct type. This may allow passing faulty parsers to eslint which would otherwise be stopped due to type checking. In use cases such as sharable configs, this may allow issues to go undetected when they would otherwise be detected at compile time. |
bradzacher commentedJan 18, 2024
Sorry - you may have misunderstood me. I mean cases like DefinitelyTyped/types/eslint/index.d.ts Lines 67 to 73 in4153f49
There's no requirement that it returns an estree Or
To be honest the entire scope manager bit of the ESLint is wrong too in this case - because there's no requirement that a parser returns anything like this - a parser need only return something vaguely looking like Then there's also things like the But at the same time the code path selectors are now completely generically typed - to the point of being pretty useless. DefinitelyTyped/types/eslint/index.d.ts Lines 649 to 669 in4153f49
They now will be typed to return a node of the form Similarly the methods on What I'm saying is that making this loose like this makes the config usecase easier - for sure. But it trades off against making the typed rule usecase really really hard. I'd actually guess that this would end up needing to be a breaking change because it would physically break codebases that use the types for that usecase. I don't think making everything loose for the sake of the config is the best approach. It's some shaky middle ground that provides the worst of all worlds. If you're really looking to keep on this particular route then IMO we need to make the entire codebase generic with type parameters for the AST so that users can provide their own AST types everywhere whilst still defaulting to the ESTree types as a useful base. But that is a massive undertaking and would require much testing. I think narrowing the changes to the flat config would be best to keep the impact small so we don't break any existing usecases whilst also supporting the new ones. |
bradzacher left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
RC for the above comment.
typescript-bot commentedJan 18, 2024
@Logicer16 One or more reviewers has requested changes. Please address their comments. I'll be back once they sign off or you've pushed new commits. Thank you! |
4153f49 to363e1f5Comparemostpinkest commentedJan 19, 2024
You've raised some good points. Making the required corrections would be a massive undertaking especially when it doesn't seem eslint documents the interface required of parsers doing "customized scope analysis", instead only describing their own As for the nodes, while it may be possible for those using these types to use a simple type guard function which indexes
That case is more likely an issue with the parser as it undermines the runtime type checking which the Regardless, the strict parser typing may be something worth coming back to if/when these types are rewritten, but at this point I'll just simplify the config and have updated the pr to modify reflect that. |
typescript-bot commentedJan 19, 2024
Hey @Logicer16, 😒 Your PR doesn't modify any tests, so it's hard to know what's being fixed, and your changes might regress in the future. Please consideradding tests to cover the change you're making. Including tests allows this PR to be merged by yourself and the owners of this module. This can potentially save days of time for you! |
typescript-bot commentedJan 19, 2024
@bradzacher Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
JoshuaKGoldberg commentedJan 21, 2024
Good timing!JoshuaKGoldberg/eslint-plugin-package-json#125 ->ota-meshi/jsonc-eslint-parser#198 provides justification fo allowing non-ESTree AST nodes. In short: when nodes aren't a flavor of JavaScript, such as with ota-meshi/jsonc-eslint-parser#198 (comment) has the suggestion of allowing Btw, +1 to the bot's request for tests corresponding to this change. |
typescript-bot commentedJan 29, 2024
@JounQin,@JoshuaKGoldberg Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
typescript-bot commentedJan 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
⏳ Hi @Logicer16, It's been a few days since this PR was approved by JounQin, bradzacher and we're waiting for a DT maintainer to give a review. If you would like to short-circuit this wait, you can edit some of thetest files in the package which verify how the |
Uh oh!
There was an error while loading.Please reload this page.
typescript-bot commentedJan 29, 2024
@Logicer16 One or more reviewers has requested changes. Please address their comments. I'll be back once they sign off or you've pushed new commits. Thank you! |
JoshuaKGoldberg commentedFeb 3, 2024
Haha, yeah, I'm a big proponent ofnot using Filed an issue on typescript-eslint here:typescript-eslint/typescript-eslint#8347 |
typescript-bot commentedFeb 26, 2024
@Logicer16 I haven't seen any activity on this PR in more than three weeks, and it still has problems that prevent it from being merged. The PR will be closed on Mar 4th (in a week) if the issues aren't addressed. |
bradzacher left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
FWIW we just shipped flat config support in typescript-eslint.
To make things compatible with the@types/eslint types as well as other ASTs I went with the loose types for flat configs:
- https://github.com/typescript-eslint/typescript-eslint/blob/4bc6944f880570273d8486d07bbac63186c8dfe0/packages/utils/src/ts-eslint/Parser.ts#L19-L52
- https://github.com/typescript-eslint/typescript-eslint/blob/4bc6944f880570273d8486d07bbac63186c8dfe0/packages/utils/src/ts-eslint/Processor.ts#L49-L86
- https://github.com/typescript-eslint/typescript-eslint/blob/4bc6944f880570273d8486d07bbac63186c8dfe0/packages/utils/src/ts-eslint/Rule.ts#L645-L678
And I also omitted theconfigs from a plugin definition to ensure there's no clash with the legacy configs.
https://github.com/typescript-eslint/typescript-eslint/blob/4bc6944f880570273d8486d07bbac63186c8dfe0/packages/utils/src/ts-eslint/Config.ts#L168-L176
So I'll reiterate that I'm strongly in favour of this approach - so much so that I "put my money where my mouth is" and shipped it.
@JounQin if you want to block this in lieu of your dream of a fully generic library definition I'll just say that I disagree with you and think you're making the wrong trade-off. But I obviously can't do anything to change your mind in that so I wish you all haste in designing and implementing that so that we can unbreak users ASAP.
This is my final stamp.
@JounQin
If you are putting your foot down and blocking this for the generic system - please comment so that @Logicer16 can know to close the PR.
Otherwise please stamp this so that it can land.
JounQin commentedFeb 27, 2024
Oh, sorry I was busy on business work and forgot this PR. I was against with I'll try to migrate to declaration merging in another PR. |
typescript-bot commentedFeb 27, 2024
@JoshuaKGoldberg Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
typescript-bot commentedFeb 27, 2024
typescript-bot commentedFeb 27, 2024
@Logicer16: Everything looks good here. I am ready to merge this PR (ate1705c2) on your behalf whenever you think it's ready. If you'd like that to happen, please post a comment saying:
and I'll merge this PR almost instantly. Thanks for helping out! ❤️ (@pmdartus,@j-f1,@saadq,@JasonHK,@bradzacher,@JounQin: you can do this too.) |
mostpinkest commentedFeb 27, 2024
Ready to merge |
Uh oh!
There was an error while loading.Please reload this page.
Please fill in this template.
pnpm test <package to test>.If changing an existing definition:
package.json.(Original Changes for reference)
Loosens the types for the parser in a flat config to allow for ones which output a custom AST which does not extend ESTree's AST.
With the new flat config files, it allows for the config, and consequently the parser, to the typechecked. In its current state a compile-time error will occur on most uses of a custom parser.