Perfectionist

sort-union-types

Enforce sorted TypeScript union types.

Adhering to this rule ensures that union types are consistently sorted, resulting in cleaner and more maintainable code. By promoting a standardized ordering of union types, this rule makes it easier for developers to navigate and understand the structure of type unions within the codebase.

Consistently sorted union types enhance the overall clarity and organization of your code.

Important

If you use the sort-type-constituents rule from the @typescript-eslint/eslint-plugin plugin, it is highly recommended to disable it to avoid conflicts.

Try it out

Options

This rule accepts an options object with the following properties:

type

default: 'alphabetical'

Specifies the sorting method.

  • 'alphabetical' — Sort items alphabetically (e.g., “a” < “b” < “c”).
  • 'natural' — Sort items in a natural order (e.g., “item2” < “item10”).
  • 'line-length' — Sort items by the length of the code line (shorter lines first).

order

default: 'asc'

Determines whether the sorted items should be in ascending or descending order.

  • 'asc' — Sort items in ascending order (A to Z, 1 to 9).
  • 'desc' — Sort items in descending order (Z to A, 9 to 1).

ignoreCase

default: true

Controls whether sorting should be case-sensitive or not.

  • true — Ignore case when sorting alphabetically or naturally (e.g., “A” and “a” are the same).
  • false — Consider case when sorting (e.g., “A” comes before “a”).

groups

default: []

Allows you to specify a list of union type groups for sorting. Groups help organize types into categories, making your type definitions more readable and maintainable. Multiple groups can be combined to achieve the desired sorting order.

There are a lot of predefined groups.

Predefined Groups:

  • 'conditional’ — Conditional types.
  • 'function’ — Function types.
  • 'import’ — Imported types.
  • 'intersection’ — Intersection types.
  • 'keyword’ — Keyword types.
  • 'literal’ — Literal types.
  • 'named’ — Named types.
  • 'object’ — Object types.
  • 'operator’ — Operator types.
  • 'tuple’ — Tuple types.
  • 'union’ — Union types.
  • 'nullish’ — Nullish types (null or undefined).
  • 'unknown’ — Types that don’t fit into any group entered by the user.

Example using all predefined groups:

type Example =
  // 'conditional' — Conditional types.
  | (A extends B ? C : D)
  // 'function' — Function types.
  | ((arg: T) => U)
  // 'import' — Imported types.
  | import('module').Type
  // 'intersection' — Intersection types.
  | (A & B)
  // 'keyword' — Keyword types.
  | any
  // 'literal' — Literal types.
  | 'literal'
  | 42
  // 'named' — Named types.
  | SomeType
  | AnotherType
  // 'object' — Object types.
  | { a: string; b: number; }
  // 'operator' — Operator types.
  | keyof T
  // 'tuple' — Tuple types.
  | [string, number]
  // 'union' — Union types.
  | (A | B)
  // 'nullish' — Nullish types.
  | null
  | undefined;

Groups configuration:

groups: [
  'conditional',
  'function',
  'import',
  'intersection',
  'keyword',
  'literal',
  'named',
  'object',
  'operator',
  'tuple',
  'union',
  'nullish',
],

Example 2:

Combine and sort intersection and union groups together:

type Example =
  | AnotherType
  | SomeType
  | (A & B)
  | (A | B)
  | (C & D)
  | (C | D)
  | keyof T;

Groups configuration:

groups: [
  'named',
  ['intersection', 'union'],
  'unknown',
],

Usage

Version

This rule was introduced in v0.4.0.

Resources

Table of Contents