網站搜尋

多維陣列的 Typescript 型別定義


我正在建立一個布林值的矩陣/二維陣列,我想推斷一個對 dategrid 而言不僅僅是「ANY」的類型。

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;
    });
});

如何為 dategrid 創建介面/類型,要求如下:

推斷結構:例如 dateGrid[yearIndex][possibleMonthValues]:boolean 並將月份索引限制為僅適用的月份。

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

...等等......

答案#1

基於記錄的解決方案

為了完全嚴格,我們可以透過使用 const 關鍵字從你提供的變數中推斷出合適的狹義類型。我假設年份只是舉例,因此最理想的方式是僅限制月份,並將年份保留為 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> 如果我們限制所有月份從 0 到 11,會是個好主意。如果我們只允許一部分月份,我們可以創建非排他性的 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

請注意,我使用了 Partial 工具類型,以放寬限制並允許只提供部分月份。

基於陣列的解法

如果我們想將這個用作陣列,我們可以考慮使用另一種類型的陣列:

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

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

在年份層級使用陣列的缺點是,當我們將起始點設定為 2000 年時,我們會有 1999 個未定義的值。