Semyon Novikov
Semyon Novikov

Reputation: 271

Adding a property to Array in Typescript

I'm trying to add a method to the Array object in Typescript. I've already found other solutions on SO, but none of those work for me.

My code looks like:

interface Array {
    average(): () => number;
}

Array.prototype.average = () => {
    var sum: number = 0

    for (var i = 0; i < this.length; i++)
        sum += this[i]

    if (this.length)
        return sum / this.length

    return 0
}

And I get the error: The property 'average' does not exist on value of type 'Array'

Upvotes: 6

Views: 7005

Answers (3)

Vukasin
Vukasin

Reputation: 561

Here is very simple solution (tested with typescript 1.6):

1) Define method with Array type:

interface Array<T> {
    average():number;
}

2) Implement method:

Array.prototype['average'] = function () {
    return this.reduce(function (a, b) {
        if(typeof a !== "number" || typeof b !== "number"){
            throw new Error("avg method applies only on numeric arrays.");
        }
        return a + b;
    }, 0) / this.length;
};

rendered code should be:

Array.prototype.average = function()........

Now you'll be able to call this as:

var arr:number[] = [1, 2, 3, 4, 5, 6];
arr.average()

Upvotes: 6

Karl
Karl

Reputation: 1244

Vukasin's answer is correct except that because Array, like Number is a native type you need to access it via the global namespace to augment it. so you need to do this...

declare global {
  interface Array<T> {
    average():number;
  }
}

then you can do :-

if(!Array.prototype.average )
{
  Array.prototype.average = function () {
    return this.reduce(function (a, b) {
        if(typeof a !== "number" || typeof b !== "number"){
            throw new Error("avg method applies only on numeric arrays.");
        }
        return a + b;
    }, 0) / this.length;
  }
}

Upvotes: 4

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 220944

Are you only getting an error in Visual Studio? That much is expected due to a bug in extending build-in interfaces. This should work if you're just invoking tsc.exe.

Relatedly, your code is a little off -- your declaration of average describes a function that returns a function that returns a number, rather than returning a number (you want to just write average(): number on that line). Also, because you used => instead of function() { in the implementation, you'll be binding to the wrong this value at runtime. Hope that helps!

Upvotes: 6

Related Questions