Skip to content

Bug: [no-redundant-type-constituents] Crashes with stack overflow for redundant uses of recursive array types #11787

@jeremybanka

Description

@jeremybanka

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.

Playground Link

https://typescript-eslint.io/play/#ts=5.9.3&fileType=.tsx&code=C4TwDgpgBAKgDFAvFAdgVwLYCMICcoA%2BscA2gLoBQFoksAjEsYceRUA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1ukQBNYmvAIYtaRUrTIcmyfJXyxELVBkiJo0DtEjgwAXxB6gA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

Repro Code

type T0 = number | T0[]

type T1 = T0 | T0[]

ESLint Config

import { default as TypeScriptPlugin } from "@typescript-eslint/eslint-plugin"
import * as parser from "@typescript-eslint/parser"
import type { ESLint, Linter } from "eslint"

const parserOptions = {
	project: [`./tsconfig.json`],
	sourceType: `module`,
} satisfies parser.ParserOptions

const commonRules = {
	"@typescript-eslint/no-redundant-type-constituents": `error`,
} satisfies Linter.Config[`rules`]

const configs = [
	{
		ignores: [`**/node_modules/**`],
	},
	{
		languageOptions: { parser, parserOptions },
		files: [`**/*.ts{,x}`, `eslint.config.ts`],
		plugins: {
			"@typescript-eslint": TypeScriptPlugin as unknown as ESLint.Plugin,
		},
		rules: commonRules,
	},
] satisfies Linter.Config[]

export default configs

tsconfig

{
  "include": ["index.ts", "eslint.config.ts"],
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true,
    "module": "nodenext",
    "moduleResolution": "nodenext"
  }
}

Expected Result

No crash, an error should be raised noting the redundancy of the type T1.

Actual Result

Crashes with maximum call stack size exceeded.

Additional Info

> eslint index.ts --debug

  eslint:cli CLI args: [ 'index.ts', '--debug' ] +0ms
  eslint:cli Using flat config? true +1ms
  eslint:cli Running on files +3ms
  eslint:eslint Using config loader LegacyConfigLoader +0ms
  eslint:eslint Using file patterns: index.ts +0ms
  eslint:eslint Deleting cache file at /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/.eslintcache +0ms
  eslint:config-loader Calculating config for file /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:config-loader Searching for eslint.config.js +1ms
  eslint:config-loader [Legacy]: Calculating config for /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +1ms
  eslint:config-loader [Legacy]: Using config file /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts and base path /Users/jem/dojo/disposable/tseslint-repro-stack-overflow +0ms
  eslint:config-loader Calculating config array from config file /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts and base path /Users/jem/dojo/disposable/tseslint-repro-stack-overflow +0ms
  eslint:config-loader Loading config file /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts +0ms
  eslint:config-loader Loading config from /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts +0ms
  eslint:config-loader Config file URL is file:///Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts +0ms
  eslint:rules Loading rule 'consistent-return' (remaining=291) +0ms
  eslint:rules Loading rule 'dot-notation' (remaining=290) +12ms
  eslint:rules Loading rule 'init-declarations' (remaining=289) +5ms
  eslint:rules Loading rule 'max-params' (remaining=288) +1ms
  eslint:rules Loading rule 'no-dupe-class-members' (remaining=287) +12ms
  eslint:rules Loading rule 'no-empty-function' (remaining=286) +3ms
  eslint:rules Loading rule 'no-invalid-this' (remaining=285) +9ms
  eslint:rules Loading rule 'no-loop-func' (remaining=284) +1ms
  eslint:rules Loading rule 'no-loss-of-precision' (remaining=283) +1ms
  eslint:rules Loading rule 'no-magic-numbers' (remaining=282) +1ms
  eslint:rules Loading rule 'no-restricted-imports' (remaining=281) +15ms
  eslint:rules Loading rule 'no-unused-expressions' (remaining=280) +39ms
  eslint:rules Loading rule 'no-useless-constructor' (remaining=279) +3ms
  eslint:rules Loading rule 'prefer-destructuring' (remaining=278) +6ms
  eslint:config-loader Config file /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/eslint.config.ts is not empty +404ms
  eslint:eslint 1 file(s) found in 406 ms +406ms
  eslint:eslint Linting in single-thread mode. +0ms
  eslint:config-loader Looking up cached config for /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:config-loader [Legacy]: Looking up cached config for /Users/jem/dojo/disposable/tseslint-repro-stack-overflow +0ms
  eslint:eslint-helpers File "/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts" read in 1 ms +0ms
  eslint:linter Linting code for /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts (pass 1) +0ms
  eslint:linter Verify +0ms
  eslint:linter With flat config: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:languages:js Parsing: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:languages:js Parsing successful: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +367ms
  eslint:languages:js Scope analysis: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:languages:js Scope analysis successful: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:linter An error occurred while traversing +405ms
  eslint:linter Filename: /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts +0ms
  eslint:linter Line: 3 +0ms
  eslint:linter Parser Options: { project: [ './tsconfig.json' ], sourceType: 'module' } +0ms
  eslint:linter Settings: {} +0ms

Oops! Something went wrong! :(

ESLint: 9.39.0

RangeError: Maximum call stack size exceeded
Occurred while linting /Users/jem/dojo/disposable/tseslint-repro-stack-overflow/index.ts:3
Rule: "@typescript-eslint/no-redundant-type-constituents"
    at isSimpleTypeRelatedTo (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/typescript/lib/typescript.js:68338:33)
    at isRelatedTo (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/typescript/lib/typescript.js:68755:163)
    at checkTypeRelatedTo (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/typescript/lib/typescript.js:68466:20)
    at isTypeRelatedTo (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/typescript/lib/typescript.js:68399:14)
    at Object.isTypeAssignableTo (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/typescript/lib/typescript.js:67525:12)
    at isTargetTypeRedundantInUnion (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-redundant-type-constituents.js:290:20)
    at isTargetTypeRedundantInUnion (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-redundant-type-constituents.js:214:33)
    at isTargetTypeRedundantInUnion (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-redundant-type-constituents.js:205:33)
    at isTargetTypeRedundantInUnion (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-redundant-type-constituents.js:264:16)
    at isTargetTypeRedundantInUnion (/Users/jem/dojo/disposable/tseslint-repro-stack-overflow/node_modules/@typescript-eslint/eslint-plugin/dist/rules/no-redundant-type-constituents.js:214:33)

Metadata

Metadata

Assignees

No one assigned

    Labels

    accepting prsGo ahead, send a pull request that resolves this issuebugSomething isn't workingpackage: eslint-pluginIssues related to @typescript-eslint/eslint-plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions