5

I have the following prototype extension because I've been using a lot of reduce:

declare interface Array<T> {
    sum(): T;
}

Array.prototype.sum = function() {
    return this.reduce((acc, now) => acc + now, 0);
};

is it possible to force this extension to be typed only for number?

1
  • Since the function sum will be available for all arrays regardless, why is this a useful thing to do? Wouldn't it make more sense to derive from Array instead? Commented Jan 2, 2018 at 13:31

1 Answer 1

8

As I wrote the question, I ended up finding out how to do it:

declare interface Array<T> {
    sum(this: Array<number>): number;
}

Object.defineProperty(Array.prototype, 'sum', {
    value: function(this: Array<number>): number {
        return this.reduce((acc, now) => acc + now, 0);
    },
});

It should also be noted that extending basic prototypes is usually not a good idea - in the event the base standard is changed to implement new functionality, there might be a conflict in your own code base. For this particular example on my particular codebase I feel it is fine, since sum is a fairly descriptive method name and very common along multiple languages, so a future standard will (probably) have a compatible implementation.

Sign up to request clarification or add additional context in comments.

3 Comments

I didn't know about enumeration on javascript types so I did a bit of research, thanks for pointing that out. I updated my own answer.
FWIW, to match how other function-valued Array.prototype properties are configured, you'd add writable: true, configurable: true to that.
@Badashi Will a warning or error be raised if someone attempts to redefine the sum prototype method?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.