Joe
Joe

Reputation: 4254

Typescript error: Property '0' is missing in number[]

My class:

class Point{
  coordinates: [number, number, number];
    constructor(coordinates: [string, string, string]) {
    this.coordinates = coordinates.map((coordinate) => {
      return Math.round(parseFloat(coordinate) *100)/100;
    })
  }
}

The error I'm getting:

`Property '0' is missing in number[]`

demo

What is wrong?

Upvotes: 0

Views: 1081

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250416

coordinates is a tuple type. In Typescript tuples inherit from arrays, and the methods available on tuples actually come from Array<T>. While this is useful, these methods return arrays nto tuples when called. So even though you call map on a tuple with 3 elements, and you would expect the result tu be a tuple with 3 elements, it will actually be an array.

The simplest solution is to use a type assertion to tell the compiler the result will be a tuple with 3 numbers:

this.coordinates = coordinates.map((coordinate) => {
    return Math.round(parseFloat(coordinate) * 100) / 100;
}) as [number, number, number];  

Edit

Alternatively you can extend the Array global interface to correctly type the result of the map operation:

interface Array<T> {
    // up to 3 tuple items, you can add more
    map<U>(this: [T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U];
    map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U];
    map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U];
}

class Point {
    coordinates: [number, number, number];
    constructor(coordinates: [string, string, string]) {
        // Will now work as expected
        this.coordinates = coordinates.map((coordinate) => {
            return Math.round(parseFloat(coordinate) * 100) / 100;
        });
    }
}

This GitHub issue has an interesting discussion on the topic.

Upvotes: 5

Related Questions