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