Skip to content

Types: plugin and parser types incompatible with ESLint types #9110

@JstnMcBrd

Description

@JstnMcBrd

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Issue Description

I am trying to create a type-safe ESLint config using @typescript-eslint. But it appears the types are not formatted correctly.

Here is a simplified version of what I have:

import tsESLint from 'typescript-eslint';
import type { Linter } from 'eslint';

export function config(): Linter.FlatConfig[] {
    return [
        {
            plugins: {
                // Throws type error
                // The type of 'TSESLint.FlatConfig.Plugin' is not compatible with 'ESLint.Plugin'
                '@typescript-eslint': tsESLint.plugin,
            },
            languageOptions: {
                // Throws type error
                // The type of 'TSESLint.Parser.LooseParserModule' is not compatible with 'Linter.FlatConfigParserModule'
                parser: tsESLint.parser,
            },
            // ...
        },
    ];
}

Here's the error message for the plugin:

Type 'import(".../@typescript-eslint/utils/dist/ts-eslint/Config").FlatConfig.Plugin' is not assignable to type 'import("c:/Users/jstnm/OneDrive/Programming/eslint-config/node_modules/@types/eslint/index").ESLint.Plugin'.
  Types of property 'configs' are incompatible.
    Type 'SharedConfigs | undefined' is not assignable to type 'Record<string, FlatConfig<RulesRecord> | FlatConfig<RulesRecord>[] | ConfigData<RulesRecord>> | undefined'.
      Type 'SharedConfigs' is not assignable to type 'Record<string, FlatConfig<RulesRecord> | FlatConfig<RulesRecord>[] | ConfigData<RulesRecord>>'.
        'string' index signatures are incompatible.
          Type 'Config' is not assignable to type 'FlatConfig<RulesRecord> | FlatConfig<RulesRecord>[] | ConfigData<RulesRecord>'.
            Type 'Config' is not assignable to type 'FlatConfig<RulesRecord>'.
              Types of property 'files' are incompatible.
                Type '(FileSpec | FileSpec[])[] | undefined' is not assignable to type '(string | string[])[] | undefined'.
                  Type '(FileSpec | FileSpec[])[]' is not assignable to type '(string | string[])[]'.
                    Type 'FileSpec | FileSpec[]' is not assignable to type 'string | string[]'.
                      Type '(filePath: string) => boolean' is not assignable to type 'string | string[]'.

Here's the error message for the parser (slightly different between v7 and v8):

// typescript-eslint@7.9.0
Type 'LooseParserModule' is not assignable to type 'FlatConfigParserModule | undefined'.
  Type '{ meta?: { name?: string | undefined; version?: string | undefined; } | undefined; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type 'FlatConfigParserModule | undefined'.
    Type '{ meta?: { name?: string | undefined; version?: string | undefined; } | undefined; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type 'Omit<ParserModule, "parseForESLint"> & { parseForESLint(text: string, options?: any): Omit<ESLintParseResult, "ast" | "scopeManager"> & { ...; }; }'.
      Type '{ meta?: { name?: string | undefined; version?: string | undefined; } | undefined; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type '{ parseForESLint(text: string, options?: any): Omit<ESLintParseResult, "ast" | "scopeManager"> & { ast: unknown; scopeManager?: unknown; }; }'.
        The types returned by 'parseForESLint(...)' are incompatible between these types.
          Type '{ ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }' is not assignable to type 'Omit<ESLintParseResult, "ast" | "scopeManager"> & { ast: unknown; scopeManager?: unknown; }'.
            Type '{ ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }' is not assignable to type 'Omit<ESLintParseResult, "ast" | "scopeManager">'.
              Types of property 'visitorKeys' are incompatible.
                Type 'unknown' is not assignable to type 'VisitorKeys | undefined'.

// typescript-eslint@8.0.0-alpha.13
Type '{ meta?: { name?: string; version?: string; }; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type 'FlatConfigParserModule'.
  Type '{ meta?: { name?: string; version?: string; }; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type 'Omit<ParserModule, "parseForESLint"> & { parseForESLint(text: string, options?: any): Omit<ESLintParseResult, "ast" | "scopeManager"> & { ...; }; }'.
    Type '{ meta?: { name?: string; version?: string; }; parseForESLint(text: string, options?: unknown): { ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }; }' is not assignable to type '{ parseForESLint(text: string, options?: any): Omit<ESLintParseResult, "ast" | "scopeManager"> & { ast: unknown; scopeManager?: unknown; }; }'.
      The types returned by 'parseForESLint(...)' are incompatible between these types.
        Type '{ ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }' is not assignable to type 'Omit<ESLintParseResult, "ast" | "scopeManager"> & { ast: unknown; scopeManager?: unknown; }'.
          Type '{ ast: unknown; services?: unknown; scopeManager?: unknown; visitorKeys?: unknown; }' is not assignable to type 'Omit<ESLintParseResult, "ast" | "scopeManager">'.
            Types of property 'visitorKeys' are incompatible.
              Type 'unknown' is not assignable to type 'VisitorKeys'.
                Index signature for type 'string' is missing in type '{}'.

Cause

typescript-eslint is probably not used this way very often. The types are being held to a much higher standard of accuracy by requiring that they match ESLint's types. It appears there some are mistakes.

Workarounds

The plugin and parser can be force-typecasted to the correct type, but it is unsafe and not ideal.

Reproduction Repository Link

https://github.com/JstnMcBrd/typescript-eslint-repro

Repro Steps

  1. clone the repo
  2. npm install
    optionally, change versions with npm install typescript-eslint@8.0.0-alpha.13
  3. npm run build

Versions

package versions
typescript-eslint 7.9.0 (latest), 8.0.0-alpha.13 (next)
TypeScript 5.4.5 (latest)
node 20.13.1 (LTS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    accepting prsGo ahead, send a pull request that resolves this issuebugSomething isn't workinglocked due to agePlease open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy