Is it possible to define a non empty array type in 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?        
}

Leave a Comment