Rensykes
Rensykes

Reputation: 94

Mapping axios response (array of arrays) to typescript interface

I'm using an API that returns the following response:

[
  [ 1636765200000, 254.46, 248.07, 254.78, 248.05, 2074.9316693 ],
  [ 1636761600000, 251.14, 254.29, 255.73, 251.14, 5965.53873045 ],
  [ 1636758000000, 251.25, 251.15, 252.97, 249.78, 7803.5565834 ],
  ... more items
]

I use axios to make a request against it as follows:

let res = await axios.get<CandlesResponse[]>(`${baseUrl}/${pathParams}?${queryParams}`);
let {data} = res;

In this case, TS infers the following:

I'm having troubles understanding how to define the interface that gets mapped. I tried the following:

interface CandlesResponse {
    values:number[];
}

If I run, for example:

let lastCandle = data[119];
console.log(lastCandle.values)

in both cases, I got undefined as response.

While trying I managed to find something that works defining the Interface as follows:

interface CandlesResponse {
    0:[number, number, number, number, number, number];
    1:[number, number, number, number, number, number];
    2:[number, number, number, number, number, number];
    3:[number, number, number, number, number, number];
    4:[number, number, number, number, number, number];
    5:[number, number, number, number, number, number];
}

But I cannot understand why it works. I also found out (and this, to me, makes more sense since each CandlesResponse is an array of numbers) that it works also defining the interface like this:

interface CandlesResponse {
    0:number;
    1:number;
    2:number;
    3:number;
    4:number;
    5:number;
}

This allows me to get the values like this:

let lastCandle = data[119];
console.log(lastCandle[0])

obtaining 1636340400000.

I need to understand why does it work like this. In particular, why does it work in both ways:

Why the values:number[]; approach returns undefined, instead?

Also I want to understand if there is the possibility to give a proper name, instead of an index, to access those values. I want something that looks like this:

interface CandlesResponse {
    MTS:number;
    OPEN:number;
    CLOSE:number;
    HIGH:number;
    LOW:number;
    VOLUME:number;
}

...

let lastCandle = data[119];
console.log(lastCandle.MTS);

I guess I'm a bit confused and I hope someone can help me understand the problem

EDIT: I can obtain the structure that I want by doing something as follows:

interface CandlesResponse {
    0:number;
    1:number;
    2:number;
    3:number;
    4:number;
    5:number;
}

class Candle{
    MTS:number;
    OPEN:number;
    CLOSE:number;
    HIGH:number;
    LOW:number;
    VOLUME:number;

    constructor(MTS: number, OPEN: number, CLOSE: number, HIGH: number, LOW: number, VOLUME: number){
        this.MTS = MTS;
        this.OPEN = OPEN;
        this.CLOSE = CLOSE;
        this.HIGH = HIGH;
        this.LOW = LOW;
        this.VOLUME = VOLUME;
    }
}

...

    let res = await axios.get<CandlesResponse[]>(`${baseUrl}/${pathParams}?${queryParams}`);
    let {data} = res;
    let candles:Candle[] = data.map(candle => new Candle(candle[0], candle[1], candle[2], candle[3], candle[4], candle[5]))
    console.log(candles[1].CLOSE)
    

Still I cant understand why it worked defining in the CandlesResponse interface the properties like this:

0:[number, number, number, number, number, number];

I also wonder if there is a better way to do it

SUMMARY:

I want to understand if there is a way to map the response object by giving proper names to access the fields (response is an array of arrays and I want o give to each internal array's value a proper name instead of an index). Also I would like to understand how does it work

Upvotes: 1

Views: 2246

Answers (1)

Dean James
Dean James

Reputation: 2633

I think your issue is dealing with an interface that represents an array which basically has an auto incrementing key (or index).

If you create a dedicated type that represents a single Candle, and then use that to represent the shape of the response, it becomes a little easier. All you have to add is `[index: number]' to represent the index and it should work:

// Named this way to avoid clash with the existing Candle class
type CandleType = [number, number, number, number, number, number];

interface CandlesResponse {
    [key: number]: CandleType
}

Upvotes: 1

Related Questions