Reputation: 94
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
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