Is it possible to define a non empty array type in Typescript?

Typescript

Typescript Problem Overview


I have a list of numbers that I know is never empty. Is it possible to define an array in Typescript that is never empty?

I know that it is possible with tuples like [ number, number ] but this will not work as my array can be any size.

I guess what I am looking for is a NonEmptyArray<number> type.

Does it exist? :)

Typescript Solutions


Solution 1 - Typescript

A feature request for allowing you to just check array.length > 0 to guard against empty arrays, microsoft/TypeScript#38000, was declined as being too complex. Essentially you cannot usually simply check length in TypeScript to convince the compiler about the availability of properties at given numeric keys.

You can define a non-empty array type like this:

type NonEmptyArray<T> = [T, ...T[]];

const okay: NonEmptyArray<number> = [1, 2];
const alsoOkay: NonEmptyArray<number> = [1];
const err: NonEmptyArray<number> = []; // error!

This is due to support added in TS 3.0 for rest elements in tuple types. I'm not sure what your use case is... It's probably more annoying to use that type than you expect, though:

function needNonEmpty(arr: NonEmptyArray<number>) {}
function needEmpty(arr: []) {}

declare const bar: number[];
needNonEmpty(bar); // error, as expected

if (bar.length > 0) {
    needNonEmpty(bar); // ugh, still error!
}

If you want a length check to work, you'll need to use something like a user-defined type guard function, but it's still annoying to use:

function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> {
    return arr.length > 0;
}

if (isNonEmptyArray(bar)) {
    needNonEmpty(bar); // okay
} else {
    needEmpty(bar); // error!! urgh, do you care?        
} 

Anyway hope that helps. Good luck!

Solution 2 - Typescript

I've also wondered about this and came up with a different solution:

type NonEmptyArray<T> = T[] & { 0: T };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmspoulsenView Question on Stackoverflow
Solution 1 - TypescriptjcalzView Answer on Stackoverflow
Solution 2 - TypescriptAndrei Vajna IIView Answer on Stackoverflow