#26766·oxc

linter: Add a type-aware rule to detect usage of never values

Author: mathcovaxCreated Sep 17, 2026Updated Sep 18, 2026
LabelsA-linter

It would be useful to add a TypeScript type-aware rule that reports when a value whose inferred type has been narrowed to never is still being used.

Since never is assignable to every type in TypeScript, this remains valid:

consume(value); // `value` is `never`

This can hide dead code or logic mistakes, especially when narrowing happens through predicates and functional abstractions.

Example

A concrete case can happen inside a pipeline:

const result = pipe(
	right("success"),
	when(
		isLeft,
		(value) => {
			value satisfies never;

			consume(value); // accepted by TypeScript
			return value;
		},
	),
);

Here, right("success") produces a value already known to be a Right.

The isLeft predicate narrows its input using:

Extract<Input, Left>

In this context:

Extract<Right, Left>

resolves to never.

TypeScript therefore correctly infers that value is never, which can be verified with:

value satisfies never;

However, consume(value) is still accepted because never is assignable to any type.

The callback can never be executed at runtime, so this is effectively dead code.

TypeScript Playground reproduction

Why no-unnecessary-condition is not enough

typescript/no-unnecessary-condition works well when the condition is directly visible to the linter.

In this example, however, the control flow is encapsulated inside a function such as when.

The linter does not need, and probably should not need, to understand the semantics of when, pipe, match, or similar abstractions.

The type checker already has the relevant information: the value passed to the callback is never.

Proposed behavior

A rule such as:

typescript/no-never-value

could report usages of expressions whose resolved type is never:

consume(value);
//      ^ error: value has type `never`

const result = value;
//             ^ error

array.push(value);
//         ^ error

The goal would not be to forbid the never type itself.

Intentional uses such as exhaustiveness helpers should remain valid:

function assertNever(value: never): never {
	throw new Error("Unexpected value");
}

Motivation

This rule could help detect:

  • dead code hidden behind functional abstractions;
  • predicates applied to types they can no longer match;
  • branches made impossible after refactoring;
  • narrowing mistakes that are difficult to notice;
  • cases that no-unnecessary-condition cannot easily analyze.

The signal is relatively simple: a value that TypeScript already considers impossible (never) is still being consumed as a regular value.

AI assistance disclosure

This issue was drafted with the assistance of AI, then manually reviewed and edited before submission.

The goal of using AI here was only to help structure and phrase the proposal. The technical reasoning, example, and intent were reviewed by the author, and this issue is not intended to contribute to low-quality AI-generated issue spam or "AI slop".