0
votes

I have a generic function and I would like to make it accept only fixed length (possibly mixed type) tuples as the type argument. I do not know the possible tuple types in advance - it should accept any fixed length tuples.

doSomething<[number, string, boolean]>(); // this should be okay
doSomething<number[]>(); // this should throw a compiler error

I know that I can restrict the length to a specific number literal (array check omitted for brevity):

type LengthOf<N extends number> = {
  length: N;
}
function doSomething<T extends LengthOf<2>(){};
doSomething<[any, any]>(); // ok
doSomething<[any]>(); // error

But I can't use this method to restrict the length to any number literal, since any number literal will extend number and that's also the length type of variable length arrays.

Is this possible in TypeScript?

1

1 Answers

1
votes

I'm not sure why you want this, but you could strengthen the generic constraint so that it will only accept array types whose length property is narrower than number:

function doSomething<
    T extends (number extends T['length'] ? [] : any[])
>() { };

This will allow fixed-length tuples or ones whose length is a union of numeric literals like tuples with optional elements,

doSomething<[number, string, boolean]>(); // okay
doSomething<[number, string, boolean?]>(); // okay

while disallowing arrays or open-ended tuples (with rest elements):

doSomething<number[]>(); // error
doSomething<[number, string, ...boolean[]]>(); // error

Playground link to code