no-redundant-type-constituents
Disallow members of unions and intersections that do nothing or override type information.
Extending "plugin:@typescript-eslint/recommended-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
Some types can override some other types ("constituents") in a union or intersection and/or be overridden by some other types. TypeScript's set theory of types includes cases where a constituent type might be useless in the parent union or intersection.
Within |
unions:
any
andunknown
"override" all other union membersnever
is dropped from unions in any position except when in a return type position- primitive types such as
string
"override" any of their literal types such as""
Within &
intersections:
any
andnever
"override" all other intersection membersunknown
is dropped from intersections- literal types "override" any primitive types in an intersection
- literal types such as
""
"override" any of their primitive types such asstring
module.exports = {
"rules": {
"@typescript-eslint/no-redundant-type-constituents": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
type UnionAny = any | 'foo';
type UnionUnknown = unknown | 'foo';
type UnionNever = never | 'foo';
type UnionBooleanLiteral = boolean | false;
type UnionNumberLiteral = number | 1;
type UnionStringLiteral = string | 'foo';
type IntersectionAny = any & 'foo';
type IntersectionUnknown = string & unknown;
type IntersectionNever = string | never;
type IntersectionBooleanLiteral = boolean & false;
type IntersectionNumberLiteral = number & 1;
type IntersectionStringLiteral = string & 'foo';
Open in Playgroundtype UnionAny = any;
type UnionUnknown = unknown;
type UnionNever = never;
type UnionBooleanLiteral = boolean;
type UnionNumberLiteral = number;
type UnionStringLiteral = string;
type IntersectionAny = any;
type IntersectionUnknown = string;
type IntersectionNever = string;
type IntersectionBooleanLiteral = false;
type IntersectionNumberLiteral = 1;
type IntersectionStringLiteral = 'foo';
Open in PlaygroundLimitations
This rule plays it safe and only works with bottom types, top types, and comparing literal types to primitive types.
Options
This rule is not configurable.
When Not To Use It
Some projects choose to occasionally intentionally include a redundant type constituent for documentation purposes.
For example, the following code includes string
in a union even though the unknown
makes it redundant:
/**
* Normally a string name, but sometimes arbitrary unknown data.
*/
type NameOrOther = string | unknown;
If you strongly feel a preference for these unnecessary type constituents, this rule might not be for you.
Further Reading
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting. See Performance Troubleshooting if you experience performance degredations after enabling type checked rules.