'Typescript dynamic type []

i'm new to Typescript and I stubbled an issue that I have no answer for.

Basically I am trying to feed data to Dygraph chart which takes [Date, number, number,...]. The thing is I receive multiple series of data from my API which has this format [Date, number]. Is there an elegant way in type script to switch from [Date, number][] to [Date, number, number,...] without hard coding it like I did below? I mean it works but it makes me want to vomit. Also even though it is very unlikely I would need more than 7 series in the same graph, I hate the idea that this is limited.

Anyway if you have any idea how I could get around this your help would be greatly appreciated!

export class Datapoint {
  date: Date = new Date()
  value: number | undefined
}

export class DatapointSerie {
  datapoints: Datapoint[] = new Array();
}

export class DygraphData {
  maxSeriesCount = 7
  data: [Date, number | undefined, number | undefined, number | undefined, number | undefined, number | undefined, number | undefined, number | undefined][] = []

  constructor(series: DatapointSerie[]) {
    let seriesCount = Math.min(series.length, this.maxSeriesCount)
    for (let i = 0; i < seriesCount; i++) {
      this.fillSerie(series[i], i)
    }
  }

  fillSerie(serie: DatapointSerie, index: number) {
    switch (index) {
      case 0:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, datapoint.value, undefined, undefined, undefined, undefined, undefined, undefined]))
        break
      case 1:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, datapoint.value, undefined, undefined, undefined, undefined, undefined]))
        break
      case 2:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, undefined, datapoint.value, undefined, undefined, undefined, undefined]))
        break
      case 3:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, undefined, undefined, datapoint.value, undefined, undefined, undefined]))
        break
      case 4:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, undefined, undefined, undefined, datapoint.value, undefined, undefined]))
        break
      case 5:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, undefined, undefined, undefined, undefined, datapoint.value, undefined]))
        break
      case 6:
        serie.datapoints.forEach((datapoint) => this.data.push([datapoint.date, undefined, undefined, undefined, undefined, undefined, undefined, datapoint.value]))
        break

      default:
        break
    }
  }
}


Solution 1:[1]

You can use the array spread operator to declare your array:

data: [Date, ...Array<number | undefined>][] = [];

That means any number of elements of type number or undefined may come after the date.

Then filling the series just becomes:

  constructor(series: DatapointSerie[]) {
    series.forEach((ser, index) => {
      for (const pt of ser.datapoints) {
        const res: [Date, ...Array<number | undefined>] = [pt.date];
        res[index + 1] = pt.value;
        this.data.push(res);
      }
    });
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris Hamilton