-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: add types for flat config files #7273
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
Conversation
Thanks for the PR, @bradzacher! typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community. The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately. Thanks again! 🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint. |
✅ Deploy Preview for typescript-eslint ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
68e4da9
to
96b6e74
Compare
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.
OK! From what I can tell, this is a very accurate and good representation of how things will be in the new world. But, as you mentioned in the description, this is all conjecture and guessing. I think we'd want some response to eslint/eslint#17391 eslint/eslint#17242 and/or an explicit review from someone on ESLint core. 🤷
@bradzacher now that eslint/eslint#17640 is merged, are there any changes you want to make here? |
@JoshuaKGoldberg @bradzacher while we wait for the PR merge + release, is it possible to publish a WIP version of this to npm? Or is there another easy way for package authors to help test out these new types in their projects? (before this PR is merged) Eg. some prerelease tag like |
WorkaroundFor now, I'm using /** @type {import('eslint').Linter.FlatConfig} */
const config = {
};
export default config; Types aren't as nice as the |
https://typescript-eslint.io/contributing/local-development -> https://typescript-eslint.io/contributing/local-development/local-linking would be the right way. Looks like this has some merge conflicts right now. Were it not for those and builds on |
One of the reasons I hadn't pushed forward with this was I was trying to decide if I should build some features for typing the config or not. There's a whole project around that so might be worth just not doing it for the moment. |
I assume you mean Alternative: I have been using the types directly with JSDoc and the experience hasn't been too bad. |
Yes, like that but built in. For example this is a valid config import foo from 'eslint-plugin-foo';
import bar from 'eslint-plugin-bar';
export default [
{ plugins: {foo} },
{
files: ["path1"],
plugins: {bar},
},
{
rules: {
// foo/* rules are available here
// but not bar/* rules
},
},
]; And you can see how the generics just don't work because config merging. So we'd need to go with a less sound approach (which is fine enough but not ideal). There's also the complicated thing of renaming plugins which would need to be handled. EG import foo from 'eslint-plugin-foo';
export default [
{
files: ["path1"],
plugins: {foo},
rules: {
// eslint-plugin-foo rules are available as foo/*
},
},
{
files: ["path2"],
plugins: {foobar: foo},
rules: {
// eslint-plugin-foo rules are available as foobar/*
},
},
{
rules: {
// eslint-plugin-foo rules are NOT available here
},
},
]; There's a lot of sadness with the flat config design as it was intended to be a very dynamic DSL -- which ofc sucks to strictly type. The other thing I was looking at was our schema generation tooling. To make type-safe configs work we would want a way to auto-generate types for the plugin based on the json schemas. We now have that tooling but we don't have it designed for public consumption - or even published. Theres a lot of work to do to define this space as a general solution that any plugin at all can easily leverage and users can "just use". Which is a long and rambly confirmation that this probably just needs to land as-is and the type-safe rule configs can come later. |
cc @bradzacher - GitHub won't let me request your review on your own PR (because nobody has ever swapped author/reviewer role on a PR, ever) but I think I got it merged from |
oop - @bradzacher if you want to send another PR I should be able to review before our auto-release today (I'm about to step out but will be back soon) |
/** | ||
* The definition of plugin rules. | ||
*/ | ||
rules?: Record<string, RuleCreateFunction | AnyRuleModule>; |
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 think that just specifying RuleCreateFunction
might be dead for flat configs?
I know it's deprecated I just don't know if it's dead dead.
🤷♂️ was just drive by commenting before i went to bed. |
Well, this is released in https://github.com/typescript-eslint/typescript-eslint/releases/tag/v6.11.0 (cc @karlhorky). If folks don't like it we can always fix it up 😄 |
Hmm... just trying out I first tried this: /** @type {import('@typescript-eslint/utils').TSESLint.Linter.Config[]} */
const config = [
{
plugins: {
'@next/next': next,
},
...
},
... But this resulted in the error that the type of
There was no /** @type {import('./node_modules/@typescript-eslint/utils/dist/ts-eslint/Config.js').FlatConfig[]} */ This resulted in a different error:
Is there a better way to import this type for usage in my shared config? |
@karlhorky you should be able to use import('@typescript-eslint/utils/ts-eslint').FlatConfig.ConfigArray |
Thanks! Switched over here: Still some manual work needed (see below), but looks like it's working 🙌
|
Overview
Adds in strict type definitions for the new "flat config" style config.
I took the time to do a little bit of refactoring to attempt to share as many types as possible and better organise things.
In particular I tried to move things a little so everything didn't hang off the
Linter
namespace like before.I believe I got everything right - it was pieced together from the docs. Sadly there is no json schema like with classic configs and the validation function is quite loose - so some of it is pieced together based on past config structure.
Feel free to eyeball the docs and compare them to make sure I got it right.
This change should be completely backwards-compatible - please flag if you think I made any incompatible changes though.
TODO - https://eslint.org/docs/latest/extend/plugins#metadata-in-plugins