Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript restrict maximum Array Length

Basically I want a type of an array with a maximum length of 4. Easily enough I wasn't able to find how this check can be implemented in typescript. Can someone help me out? Something like this:

const a = [item1, item2, item3, item4, *item5*] -> array has a maximum length of 4

Thanks!

like image 929
Jan Schmutz Avatar asked Dec 30 '25 07:12

Jan Schmutz


2 Answers

TypeScript has "fixed-length" array types called tuples. You can use optional tuple elements to represent an array whose length is in some range up to a maximum of 4. And I'd recommend using a readonly tuple if you want to try to maintain the length restriction:

type ArrayOfMaxLength4 = readonly [any?, any?, any?, any?];

const a: ArrayOfMaxLength4 = [item1, item2, item3, item4, item5]; // error!
//    ~ <--  Source has 5 element(s) but target allows only 4
const b: ArrayOfMaxLength4 = [item1, item2, item3]; // okay

I put "fixed-length" in quotes because tuples are represented by and typed as a special sort of Array, which has methods like push() that can change the length. Nothing stops you from pushing a value onto the end of a tuple.

const c: [number, string] = [1, "a"];
c.push(2); // oops
c.unshift("OOPS"); // big oops, totally wrong value in tuple
console.log(c); // ["OOPS", 1, "a", 2]

There was a request to stop this from happening at microsoft/TypeScript#6325, but it was declined. One way to make it harder to violate your constraint is to use a ReadonlyArray or readonly tuple which does not expose any methods to let you mutate the array. This might go too far if you want to modify the elements without changing the array length or element types, but it at least warns you on things like push():

b.push(5); // error
//~~~~ <-- Property 'push' does not exist on type 'ArrayOfMaxLength4'

Playground link to code

like image 110
jcalz Avatar answered Dec 31 '25 23:12

jcalz


You are working with Typescript, which gives you the added benefit of inheritance. The best way to tackle this problem is just writing one yourself:

class FixedArrad<T> extends Array<T> {

    constructor(public readonly max: number) {
        super();
    }

    public push(value: T): number {
        if (super.length !== this.max) {
            return super.push(value);
        }
        throw new Error('Reached max capacity');
    }

    // Etc
}
like image 32
Titulum Avatar answered Jan 01 '26 00:01

Titulum