Duplicate Type in Union or Intersection

ID

javascript.ts_duplicate_union_component

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

JavaScript

Tags

code-smell, copy-paste, typescript

Description

Reports a TypeScript union or intersection type that lists the same component twice:

type T = string | number | string;     // duplicate string
type U = Foo & Bar & Foo;              // duplicate Foo

The TypeScript compiler silently dedupes the union (or merges the intersection), so the extra entry has no effect on the resulting type.

Rationale

Duplicate components are almost always copy-paste leftovers where the developer forgot to change the second occurrence to a different type. The intent is usually visible from the surrounding code — it makes more sense as string | number | boolean than string | number | string.

Even when the duplicate is intentional ("we read both fields the same way"), the shorter form documents that intent better.

Remediation

Drop the duplicate or replace it with the intended type:

type T = string | number;
type T = string | number | boolean;
type U = Foo & Bar;

Notes

The rule compares the textual source of each component (after trimming). Structurally equivalent types written differently — for example Array<string> vs string[] — are <em>not</em> flagged: that requires a type-level equivalence engine, which is outside the scope of a static-text rule.

The rule fires once per union or intersection node, regardless of how many duplicates appear in it.