Skip to main content

prefer-type-fest-non-empty-tuple

Require TypeFest NonEmptyTuple over the ad-hoc readonly [T, ...T[]] tuple pattern.

Targeted pattern scopeโ€‹

This rule targets ad-hoc tuple-rest patterns that encode non-empty collections.

What this rule reportsโ€‹

  • readonly [T, ...T[]]

Why this rule existsโ€‹

NonEmptyTuple<T> is a well-known TypeFest alias that communicates the intent of a non-empty tuple and keeps shared utility-type usage consistent across codebases.

โŒ Incorrectโ€‹

type Names = readonly [string, ...string[]];

โœ… Correctโ€‹

type Names = NonEmptyTuple<string>;

Behavior and migration notesโ€‹

  • NonEmptyTuple<T> represents tuple/list contracts with at least one element.
  • This rule targets the explicit rest-tuple spelling (readonly [T, ...T[]]).
  • Keep element type aliases explicit when non-empty constraints are part of public API contracts.

Additional examplesโ€‹

โŒ Incorrect โ€” Additional exampleโ€‹

type Names = readonly [string, ...string[]];

โœ… Correct โ€” Additional exampleโ€‹

type Names = NonEmptyTuple<string>;

โœ… Correct โ€” Repository-wide usageโ€‹

type Steps = NonEmptyTuple<{ id: string }>;

ESLint flat config exampleโ€‹

import typefest from "eslint-plugin-typefest";

export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-type-fest-non-empty-tuple": "error",
},
},
];

When not to use itโ€‹

Disable this rule if existing tuple spellings must remain for public compatibility.

Package documentationโ€‹

TypeFest package documentation:

Source file: source/non-empty-tuple.d.ts

/**
* Matches any non-empty tuple.
*
* @category Array
*
* @example
* ```
* import type {NonEmptyTuple} from 'type-fest';
*
* const sum = (...numbers: NonEmptyTuple<number>) => numbers.reduce((total, value) => total + value, 0);
*
* sum(1, 2, 3);
* // Ok
*
* // @ts-expect-error
* sum();
* // Error: Expected at least 1 arguments, but got 0.
* ```;
*
* @see {@link RequireAtLeastOne} for objects
*/

Rule catalog ID: R050

Further readingโ€‹

Adoption resourcesโ€‹