Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass variable arguments to base class

Tags:

typescript

I want to use variable arguments in base class constructor. Same thing in derived class. The constructor can receive an unknown number of arguments, and I want to pass them to the base class constructor, for some processing. I didn't find any nice solution for that, and it seems this could be solved with spread operator, which apparently is not present in TypeScript. It will be developed in version 1.5 (am I right?):

class TSBase{
  constructor(...args: any[]){
    //do stuff with args
  }
}

class TSSomeController extends TSBase{
  constructor(...args: any[]){         
    //let base do some stuff
    //super(...args); //this doesn't work, but it would be cool... :)
  }
}

What is the best way of doing that in TypeScript? Can I use something like super.prototype.apply?

like image 763
Paolo Avatar asked Dec 30 '14 16:12

Paolo


2 Answers

As you've found out, the spread operator is not available yet.

EDIT - Sidenote: Actually, it works now in TypeScript 1.5. Just do super(...args);

As to the best way to do this pre TypeScript 1.5... it really depends, but here's one solution that doesn't involve changing any of the derived classes and keeps with what you're wanting to do:

class TSBase {
  constructor(...args: any[]) {
    if (this.constructor != TSBase && args.length === 1 && args[0] instanceof Array) {
      args = args[0];
    }

    // work with args here... for example:
    args.forEach((val) => console.log(val));
  }
}

class TSSomeController extends TSBase{
  constructor(...args: any[]){         
    super(args);
  }
}

new TSBase(3, 4);                 // 3, 4
new TSBase([3, 4]);               // Array[2]
new TSSomeController(3, 4);       // 3, 4
new TSSomeController([3, 4]);     // Array[2]
new TSSomeController([3, 4], 5);  // Array[2], 5

Basically, you can add a check in the base constructor to make the args array equal the first element only when being passed in from a derived class, when there is one argument, and when that argument is an array.

like image 145
David Sherret Avatar answered Oct 16 '22 10:10

David Sherret


In many cases having an inherited check helps. This is one of those:

class TSBase { 
  constructor( ...args: any[] ) {
    if ( this.constructor != TSBase ) args = args[0];

    //do stuff with args    
    console.log(args);
  }
}

class TSSomeController extends TSBase {  
  constructor( ...args: any[] ) {
    super(args);
  }
}


var base = new TSBase(1,2,3); // [1,2,3]
var child = new TSSomeController(1,2,3); // [1,2,3]
like image 42
basarat Avatar answered Oct 16 '22 10:10

basarat