Skip to content

linter: no-unnecessary-condition false positive on null equality check in generic function #21429

@thes01

Description

@thes01

What version of Oxlint are you using?

1.60.0 / 0.21.0

What command did you run?

oxlint --type-aware

What does your .oxlintrc.json (or oxlint.config.ts) config file look like?

{
  "plugins": ["typescript"],
  "rules": {
    "@typescript-eslint/no-unnecessary-condition": "error"
  }
}

What happened?

This issue is essentially copied from #20487 as the structure is the same, just the particular case is different. The regression most probably comes from oxc-project/tsgolint#806 which was merged in tsgolint 0.17.1 (this issue doesn't happen in 0.17.0).

no-unnecessary-condition reports "This condition will always return the same value since the types have no overlap" on value !== null where value has type (T & null) | (T & object).

typescript-eslint does not report this case.

Minimal reproduction

function _foo<T>(value: T) {
	if (typeof value === 'object' && value !== null) {
		console.log('foo');
	}
}

tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "bundler"
  },
  "include": ["*.ts"]
}

Expected behavior

No error. T is unconstrained and can be anything.

Actual behavior

  × typescript-eslint(no-unnecessary-condition): This condition will always return the same value since the types have no overlap.
   ╭─[index.ts:2:34]
 1 │ function _foo<T>(value: T) {
 2 │     if (typeof value === 'object' && value !== null) {
   ·                                     ───┬──    ──┬──
   ·                                        │        ╰── Type: null
   ·                                        ╰── Type: (T & null) | (T & object)
 3 │         console.log('foo');
   ╰────

Metadata

Metadata

Assignees

Labels

Type

Priority

None yet

Effort

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions