Bas Jansen
Bas Jansen

Reputation: 39

Can I put an 'object' interface on an Array in Typescript?

For showing a line on a map I get many data with coordinates from a REST service:

{
  "name": "line1"
  "route": [["2015-03-26T23:29:57",-0.9,-81.8],["2015-03-26T23:34:58",-0.9,-81.8],["2015-03-26T23:39:59",-0.8,-81.8],...]
}

Because of the many data in JSON I am using an array (with Timestamp, Latitude, Longitude), instead of an object, because then I would have double the size of the response (because of repeating the property names).

I have an interface:

export interface ILine {
    name: string
    route: IWaypoint[]
}

Now I would like to call:

public handleResponse(line: ILine) {
    for (var i in line.route) {
        var waypoint = line.route[i];
        var timestamp: string = waypoint.timestamp;
        var lat: number = waypoint.latitude;
        var lon: number = waypoint.longitude;
    }
}

But is that possible? How should I implement the interface IWaypoint?

This works for type-safety, but I still can not use property names:

  export interface IWaypoint extends Array<Date | number> {
    0: Date
    1: number
    2: number
  }

I still have to remember that the latitude is on position 1.

When using 'constants' (var or enum) for the index, Typescript is not able to determine the type.

const wpLatitude = 1;
var lat: number = waypoint[wpLatitude]; // <- error: Argument of type 'number | Date' is not assignable to parameter of type 'number'

enum WaypointIndex {
  TIMESTAMP,
  LATITUDE,
  LONGITUDE
}

var lat: number = waypoint[WaypointIndex.LATITUDE]; // <- error

Upvotes: 1

Views: 596

Answers (1)

zlumer
zlumer

Reputation: 7004

TypeScript tries not to modify ouput JS most of the time, so if you want to access named fields on an array, your best bet is to convert it to an object:

var route = line.route.map((wp) =>
{
    return { timestamp: wp[0], latitude: wp[1], longitude: wp[2] };
});

Upvotes: 1

Related Questions