@typescript-eslint/no-redundant-type-constituents
Disallow members of unions and intersections that change nothing or swallow the rest
Also called typescript-eslint/no-redundant-type-constituents, typescript/no-redundant-type-constituents
Some members of a union or an intersection don't do what they look like they do. "draft" | string is string, so the editor no longer suggests "draft", and a typo in it is accepted. User | any is any, so nothing about it is checked.
| Written | What TypeScript makes of it |
|---|---|
T | any, T & any | any |
T | unknown | unknown |
T | never, T & unknown | T |
T & never | never |
"draft" | string, 0 | number, true | boolean | The wider type. |
"draft" & string, 0 & number | The literal. |
T | never is allowed as the return type of a function.
bun lint --type-aware turns this rule on in TypeScript files.
Configure#
Off by default. This rule needs types, so turning it on makes bun lint type check your code first.
[lint.rules]
"@typescript-eslint/no-redundant-type-constituents" = "error" # or "warn"Examples#
type Status = "draft"draft is overridden by string in this union type. | "published"published is overridden by string in this union type. | string;
type Payload = { id: number } | anyany overrides all other types in this union type.;
type Result = string | nevernever is overridden by other types in this union type.;
function send(body: unknownunknown overrides all other types in this union type. | string) {}type Status = "draft" | "published";
type Payload = { id: number } | string;
type Result = string;
function send(body: unknown) {}
function load(id: number): string | never {
throw new Error(`No item ${id}`);
}The rule looks through type aliases:
type Id = number;
type Key = Id | 00 is overridden by number in this union type.;A type that can't be resolved acts as any, so it's reported too. Here ./missing doesn't exist:
import type { User } from "./missing";
type Owner = UserUser is an error type that acts as any and overrides all other types in this union type. | string;