1

I have an array. I want to add a method which is called whenever push is called on the array.

How do I write that in typescript?

I have tried:

 addEvent(myArray) {
    let _this = this;
    myArray.push = function() {
        Array.prototype.push.apply(myArray, arguments);
        _this.onAddItem(arguments);
    };
}

It give a compile time error: Supplied parameters do not match any signature of call target Expected 0, invoked with two.

I don't understand what it is saying.

Greg Gum
  • 33,478
  • 39
  • 162
  • 233
  • Has ben asked before: [How to extend Array.prototype.push()?](http://stackoverflow.com/questions/572604/how-to-extend-array-prototype-push) – Code Spirit Sep 24 '16 at 01:50
  • Yes, this is where I got the example. But I can't get this to work in Typescript. So my question is how to use in Typescript. – Greg Gum Sep 24 '16 at 01:56
  • You arent returning your `apply`. Keep calm and take a more detailed look to the answer in the other post. – Code Spirit Sep 24 '16 at 01:57

1 Answers1

3

Instead of using arguments, a more TS approach (and a better ES2015 approach in general) is to use rest parameters. I'm not exactly sure what you are trying to do, but you can use rest parameters like this:

addEvent(myArray) {
   // use an arrow function so you can avoid creating _this
   myArray.push = (...args: any[]) => {
        Array.prototype.push.apply(myArray, args);
        this.onAddItem(arguments);
    };
}

Then you can call addEvent like this:

let arrayLikeObject = new SomeObjecct();
myObj.addEvent(arrayLikeObject);

arrayLikeObject.push(1, 2, 3);

But, there's something not quite right about this approach. With TS, you should be providing stricter type annotations on your parameters. What type is myArray? What type of args does it accept? This should be explicitly spelled out. If it turns out that it accepts a wide variety of types, then that would indicate poor design as well.


EDIT

Now that I know what you are trying to do, I can see that the function declaration should look more like this:

    (myArray as any[]).push = (...args: any[]): number => {
        Array.prototype.push.apply(myArray, args);
        this.onAddItem(arguments);
        return myArray.length;
    };
Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148
  • `myArray` is an `Array` – Greg Gum Sep 24 '16 at 02:18
  • But I still get the same error compile error on `Array.prototype.push.apply(myArray, args);` – Greg Gum Sep 24 '16 at 02:19
  • I just want to get notified when an item is added to the array, so I can decorate the item. – Greg Gum Sep 24 '16 at 02:21
  • You should be using `any[]` as the type, then. And the type of push needs to return a number. – Andrew Eisenberg Sep 24 '16 at 02:25
  • Ok, I added the any[] type. But I don't understand what you mean by `And the type of push needs to return a number.` – Greg Gum Sep 24 '16 at 02:28
  • 1
    Array.prototype.push returns the new length of the array. In order to be semantically compatible, your function must do the same. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push – Andrew Eisenberg Sep 24 '16 at 02:29
  • Ah I see. Ok, I tried what you wrote on the Edit, but the second line still gives the same compile error message. – Greg Gum Sep 24 '16 at 02:32
  • Maybe it's a typescript issue - the code does compile and produces javascript and it looks ok to me. It's just in Visual Studio 2015 editor that it shows the error. I really appreciate you helping me out with this! – Greg Gum Sep 24 '16 at 02:35
  • Hmmm...I'm trying that in sublime text with the TS plugin enabled and I'm not getting an error. Maybe the problem has to do with code that you are not showing? – Andrew Eisenberg Sep 24 '16 at 02:37
  • I don't know the UI issue, but the code works great so I am going to credit you with the answer. Again, thank you. – Greg Gum Sep 24 '16 at 02:45
  • This quieted the compiler: `(Array.prototype.push as any).apply(myArray, args);` – Greg Gum Sep 24 '16 at 02:48
  • It kind of goes against the spirit of TS to use `any` gratuitously. If you can paste a self-contained snippet in a new question, we can figure out why the compiler is complaining. – Andrew Eisenberg Sep 24 '16 at 03:36