11

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!

AbsoluteBeginner
  • 2,160
  • 3
  • 11
  • 21
Jan Schmutz
  • 799
  • 3
  • 10
  • 28
  • 4
    It's unclear what you're asking for. Are you asking for a type which dictates an array with a max length of 4? – Aplet123 Dec 29 '20 at 16:19
  • 4
    Does this answer your question? [How to declare a Fixed length Array in TypeScript](https://stackoverflow.com/questions/41139763/how-to-declare-a-fixed-length-array-in-typescript) – pilchard Dec 29 '20 at 16:20
  • @Aplet123 yes exactly I made an edit – Jan Schmutz Dec 29 '20 at 16:27

4 Answers4

17

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

jcalz
  • 264,269
  • 27
  • 359
  • 360
1

You can try with Object.seal()...when you try to push an additional element it throws an error.

var arr: number[] = new Array(4);
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
Object.seal(arr); //Can make changes to the existing elements remaining part of it is immutable
for (var i = 0; i < arr.length; i++) {
  arr[i] = i * 3
  console.log(arr[i])
}
arr.push(20); //Error inserting an element into the array (Find it in the console)
for (var i = 0; i < arr.length; i++) {
  console.log(arr[i]) //Prints only 4 elements
}
Ram Sankhavaram
  • 1,218
  • 6
  • 11
1

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
}
Titulum
  • 9,928
  • 11
  • 41
  • 79
0

use array.slice(4) if you are working on already exist array or const a = new Array(4)

Thanks.

Hari Krishna
  • 2,372
  • 2
  • 11
  • 24