Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript typing for a Multi Dimensional Array

I am creating a matrix / 2d array of booleans and I want to infer a type that isn't simply "ANY" for dategrid.

let yearRange = [2000,2001,2002,2003,2004];
let monthRange = [0,1,2,3,4,5,6,7,8,9,10,11];
let dateGrid = any;

yearRange.forEach((year) => {
    monthRange.forEach((month) => {
        dateGrid[year][month] = true;
    });
});

How does one create an interface / type for dategrid that:

Infers the structure: e.g. dateGrid[yearIndex][possibleMonthValues]:boolean And restricts the months index to only the applicable months.

dateGrid[2000][0] = true
dateGrid[2000][1] = true
dateGrid[2000][2] = true
dateGrid[2000][3] = true
dateGrid[2000][4] = true
dateGrid[2000][5] = true
dateGrid[2000][6] = true
dateGrid[2000][7] = true
dateGrid[2000][8] = true
dateGrid[2000][9] = true
dateGrid[2000][10] = true
dateGrid[2000][11] = true
dateGrid[2001][0] = true

... and so on ...

like image 333
Paul Deschamps Avatar asked Apr 25 '26 07:04

Paul Deschamps


1 Answers

Record based solution

To be totally strict we can infer the proper narrowed types from variables you have given by using const keyword. As I assume years are only example, so the sweet spot would be only restrict months, and leave years as number:

// use const in order to get proper types
let yearRange = [2000,2001,2002,2003,2004];
let monthRange = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] as const;
type Month = typeof monthRange[number];

let dateGrid: Record <number,Record<Month, boolean>>;

Record<Month, boolean> will be good idea if we restrict to have all months from 0 to 11. If we allow on only part of months in the year we can create non-exlusive Record:

let dateGrid: Record<number, Partial<Record<Month, boolean>>> = {
  [2000]: {
    "0" : false 
  }
} // valid as not all fields needs to be provided
const a = dateGrid[2000][4] // boolean | undefined

// in contrary exclusive type
let dateGridExclusive: Record<number, Record<Month, boolean>> = {
  [2000]: {
    "0" : false 
  }
} // error all months need to be provided
const b = dateGrid[2000][4] // boolean

Pay attention that I have used Partial utility type in order to loose the constraint and allow on part of months to be provided.


Array based solution

If we want to use this as array we can perform another array type consider:

type Months = [
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
  boolean,
]

let dateGrid: Months[] // array of 12 element tuples

The minus of using array at year level is that when we set start point of such from 2000, we have 1999 undefined values.

like image 163
Maciej Sikora Avatar answered Apr 28 '26 20:04

Maciej Sikora



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!