Search code examples
typescripttype-definition

Type definition: An array of a certain type at least with e.g. 2 elements


Maybe that's a stupid question, but I would like to know if there is a possibility to say, "foo" must have at least 2 array elements of type "Foo"?

let foo: Array<Foo>; // how to say at least 2 Foos?

Solution

  • Yes, you can use a rest element in a tuple type:

    let foo: [Foo, Foo, ...Foo[]];
    

    And the compiler will enforce it:

    declare const f: Foo;
    foo = [f, f, f]; // okay
    foo = [f, f]; // okay
    foo = [f]; // error, property "1" is missing
    foo = []; // error, properties "0" and "1" are missing
    

    Of course, the compiler won't easily be able to verify that some arbitrary Foo[] matches this, even if you do the "obvious" length check:

    declare const fooArray: Foo[];
    foo = fooArray; // error, can't verify
    if (fooArray.length >= 2) {
      foo = fooArray; // error, still can't verify
    }
    

    So you might find yourself in need of something like a user-defined type guard function to convert a Foo[] to a [Foo, Foo, ...Foo[]]:

    function isAtLeastTwoFoos(x: Foo[]): x is [Foo, Foo, ...Foo[]] {
      return x.length >= 2;
    }
    

    And then you can test that way.

    if (isAtLeastTwoFoos(fooArray)) {
      foo = fooArray; // okay
    }
    

    Hope that helps; good luck!

    Link to code