18

Is there a way in typescript define fixed size array. say, for example, in a function definition, I need to able to say

coord: (c:any) => number[]; //how to say it is an array of size 4

can I define an interface like we define a hash map

//this doesn't work
interface IArray{
  [number]
}

and also restrict max length to be 4.

1
  • 1
    I wish you could do let a: number[2] = [ 0, 1 ] Commented Jan 25, 2017 at 22:15

4 Answers 4

22

You could return a tuple instead of an array:

type array_of_4 = [number, number, number, number];

var myFixedLengthArray :array_of_4 = [1,2,3,4];

// the tuple can be used as an array:
console.log(myFixedLengthArray.join(','));
Sign up to request clarification or add additional context in comments.

1 Comment

This does not restrict the array to a size of four, going beyond the fourth element will still work...
7

It's sort of awkward, but you can do it like this:

interface SizeFour<T> {
    0: T;
    1: T;
    2: T;
    3: T;
}

function fn(): SizeFour<string> {
    // Need to cast
    return <any>['', '', '', ''];   
}

var x = fn();
var a = x[0]; // a: string
var b = x[4]; // b: any; error if --noImplicitAny

1 Comment

thanks Ryan, but nothing prevent doing var c = x[10]. so no safety on the bounds. How this is possible as 10 (index/method) is not defined in the interface.
4

Preventing someone from using an index into an array outside the bounds is not something that even C# can do. e.g. what is preventing you from doing :

var index = 123; 
sizeFour[index];

Or even requesting the index from the server?

So short answer "there isn't a declarative way of preventing this if you insist on using []"

You could always do

var bar = {
   one : 'something',
   two: 'somethingelse'
   // etc. 
}

and then only use . i.e. bar.one

Comments

0

There is a (hacky) way of doing that. It's basically adding a new optional element, which is the impossible type never, to the inner array interface. However, that doesn't work if the third element is undefined.

The code below is with the latest Typescript v4.3.2:

TS playground link

interface ArraySizeOfTwo {
  0: number;
  1: number;
  2?: never;
}

interface ArrayList {
  [index: number]: ArraySizeOfTwo;
}

const myArray: ArrayList = [
  [1, 2],
  [15, 20],
];

// Error: Type 'number' is not assignable to type 'undefined'.
const myArray2: ArrayList = [
  [1, 2, 3],
  [15, 20],
];

// Error: Property '1' is missing in type '[number]' but required in type 'ArraySizeOfTwo'.
const myArray3: ArrayList = [
  [1, 2],
  [15],
];

// Error: Type 'undefined' is not assignable to type 'number'.
const myArray4: ArrayList = [
  [1, 2],
  [15, undefined],
];

// no errors :(
const myArray5: ArrayList = [
  [1, 2],
  [15, 20, undefined],
];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.