Coder Social home page Coder Social logo

Comments (6)

auvred avatar auvred commented on June 12, 2024 2
            plugins: {
                // Throws type error
                // The type of 'TSESLint.FlatConfig.Plugin' is not compatible with 'ESLint.Plugin'
                '@typescript-eslint': tsESLint.plugin,
            },

Yup, thanks for reporting! This issue has interesting story:

  1. typescript-eslint didn't allow to pass (filePath: string) => boolean to files property - #8467
  2. temporary stubbed on typescript-eslint side - #8460
    // The function form is undocumented but allowed:
    // https://github.com/eslint/eslint/issues/18118
    //
    // We have to support it as well because the DefinitelyTyped configs define it
    // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e26919eb3426f5ba85fed394c90c39efb217037a/types/eslint/index.d.ts#L1208-L1223
    //
    // If we don't then users can't use shareable configs defined using the DT types
    // https://github.com/typescript-eslint/typescript-eslint/issues/8467
    export type FileSpec = string | ((filePath: string) => boolean);
  3. reported on ESLint side, agreed to remove (filePath: string) => boolean from @types/eslint - eslint/eslint#18118
  4. removed (filePath: string) => boolean from @types/eslint- DefinitelyTyped/DefinitelyTyped#69210

So it's time to finish this journey and remove (filePath: string) => boolean added in step (2) from our types!

Although I'm not sure whether to consider this as a bug fix or a breaking change?

cc @bradzacher


            languageOptions: {
                // Throws type error
                // The type of 'TSESLint.Parser.LooseParserModule' is not compatible with 'Linter.FlatConfigParserModule'
                parser: tsESLint.parser,
            },

Looks like a duplicate of #8613

from typescript-eslint.

bradzacher avatar bradzacher commented on June 12, 2024 2

No it's a fix - that signature was only added to keep the ESLint types happy and it's not used by anyone.

It was only ever added due to the original flat config author for @types/eslint reading the implementation of the flat config package. It's never been a documented thing and only existed so flat configs could handle some obscure eslintrc feature.

But it was never part of the public API - hence it was removed. So yeah we delete it too and close the loop on this silly issue!

from typescript-eslint.

bradzacher avatar bradzacher commented on June 12, 2024 1

Type compatibility != runtime compatibility.
We are the parser that allows you to use typescript with eslint and we are 110% compatible at runtime.

As I explained #8613 (comment) - our types are designed to be permissive so you have a good DevX, but @types/eslint's types are designed to exactly describe what is allowed.

Here is a simplified example of what I mean:

// typescript-eslint
type LooseParser = string;
type Parser = 'value';
export const parser: Parser;
export type Config = { parser?: LooseParser };

// @types/eslint
type Parser = 'value';
export const parser: Parser;
export type Config = { parser?: Parser };

Our parser types are strictly defined to match the runtime types - same as @types/eslint.
However unlike @types/eslint our config type is intentionally defined loosely. This widens the things you're allowed to pass to your config.
But why? Well to account for differences in types that packages may define.
In reality ESLint is much more permissive than what @types/eslint defines - for example eslint allows any AST as long as it follows a very, very basic structure - but a lot of @types/eslint only accepts the JS/estree AST. Until recently that was the only ast you could use with the config (I had to push hard to get them to loosen that type to allow our AST to be assigned).

To clearly state our intent: our types are designed to be as permissive as possible so that you can assign anything valid from the ecosystem. They are not designed to be compatible with the overly strict @types/eslint.
Our recommendation for typing your flat config is the config function defined by our flat config package

from typescript-eslint.

JstnMcBrd avatar JstnMcBrd commented on June 12, 2024

Thanks for the quick fix!


About the second type error (@bradzacher):

I see on #8613 that it was closed as "not planned" because "we purposely do not seek compatibility with @types/eslint". I'm not sure I understand why.

Sure, your parser is going to be more complicated that the Parser from @types/eslint - "their types are not designed to take into account our AST and such" - but at the API level, shouldn't it still be compatible with the parser type that ESLint is expecting? Shouldn't it at least extend the Parser, rather than being incompatible with it?

It feels unsafe to pass a parser into my config that is explicitly incompatible with the parser API that ESLint is expecting. And if it is compatible, then the types should reflect that, no?

from typescript-eslint.

JstnMcBrd avatar JstnMcBrd commented on June 12, 2024

In reality ESLint is much more permissive than what @types/eslint defines

Hmm, then it sounds like the problem is with @types/eslint. I still firmly believe that if your parser is compatible with ESLint, then the types should be compatible too. Types should correctly define what is allowed and what is not. If the ESLint types are incompatible with things that ESLint permits, then those types are inaccurate. But I can take that up with them instead. Thank you for the explanation.

from typescript-eslint.

bradzacher avatar bradzacher commented on June 12, 2024

Look at it like this.

Our types enforce best practices - for example we enforce certain rule properties are non-optional so that people that use our tooling are forced to follow those practices (like properly documenting their rule).

But @types/eslint is built with a different intention - to add types that exhaustively show what may or may not be possible.

So in that example a rule defined with @types/eslint is not assignable to our rule type (because optional properties are not assignable to required ones). From that it follows that a plugin defined with @types/eslint is not assignable to our plugin type.

We can't have that though - because some parts of the ecosystem have chosen to use @types/eslint to declare their rules/plugin!

Which is why we define these "loose" types - to widen the set of what can be provided to the config!

Our config types focus on the developer experience, not on strict and granular correctness. We aim to provide enough of a shape to the types to allow us to validate that your passing the right thing without deeply validating the types. Eg the types we declare will ensure you don't pass a parser to the place expecting a plugin - but it won't validate that the parser function's return type's visitorKeys properties is exactly a Record<string, string[]>.

from typescript-eslint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.