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.

@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

@category Array
*/

Rule catalog ID: R050

Further readingโ€‹

Adoption resourcesโ€‹