Skip to main content

prefer-type-fest-literal-union

Require TypeFest LiteralUnion over unions that mix primitive keywords with same-family literal members.

Targeted pattern scopeโ€‹

This rule targets patterns like "foo" | "bar" | string and 200 | 404 | number.

Those unions are usually better expressed with LiteralUnion, which preserves literal IntelliSense while retaining primitive assignability.

What this rule reportsโ€‹

  • String literal unions that also include string.
  • Number literal unions that also include number.
  • Boolean literal unions that also include boolean.
  • Bigint literal unions that also include bigint.

Detection boundariesโ€‹

  • โœ… Reports same-family literal-plus-primitive unions (for example "a" | string).
  • โŒ Does not rewrite cross-family unions (for example "a" | number).

Why this rule existsโ€‹

LiteralUnion<Literals, Primitive> preserves literal completions while still accepting the broad primitive type.

This keeps APIs ergonomic for known values without over-constraining extension points.

โŒ Incorrectโ€‹

type Environment = "dev" | "prod" | string;
type HttpCode = 200 | 404 | number;

โœ… Correctโ€‹

import type { LiteralUnion } from "type-fest";

type Environment = LiteralUnion<"dev" | "prod", string>;
type HttpCode = LiteralUnion<200 | 404, number>;

Behavior and migration notesโ€‹

  • Use the second parameter to match the primitive family (string, number, boolean, bigint).
  • Preserve literal member intent by keeping the literal union in the first type argument.
  • Avoid this pattern for closed enums where broad primitive assignability is not wanted.

ESLint flat config exampleโ€‹

import typefest from "eslint-plugin-typefest";

export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-type-fest-literal-union": "error",
},
},
];

When not to use itโ€‹

Disable this rule if your team prefers explicit primitive-plus-literal unions and does not want the additional abstraction.

Package documentationโ€‹

TypeFest package documentation:

Source file: source/literal-union.d.ts

/**
* Allows creating a union type by combining primitive types and literal types
* without sacrificing auto-completion in IDEs for the literal type part of the
* union.
*
* Currently, when a union type of a primitive type is combined with literal
* types, TypeScript loses all information about the combined literals. Thus,
* when such type is used in an IDE with autocompletion, no suggestions are made
* for the declared literals.
*
* This type is a workaround for
* [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729).
* It will be removed as soon as it's not needed anymore.
*
* @category Type
*
* @example
* ```
* import type {LiteralUnion} from 'type-fest';
*
* // Before
*
* type Pet = 'dog' | 'cat' | string;
*
* const petWithoutAutocomplete: Pet = '';
* // Start typing in your TypeScript-enabled IDE.
* // You **will not** get auto-completion for `dog` and `cat` literals.
*
* // After
*
* type Pet2 = LiteralUnion<'dog' | 'cat', string>;
*
* const petWithAutoComplete: Pet2 = '';
* // You **will** get auto-completion for `dog` and `cat` literals.
* ```
*/

Rule catalog ID: R048

Further readingโ€‹

Adoption resourcesโ€‹