Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do typescript function chaining?

I want to use function chaining in typescript.

Consider a class

export class numbOp(){
  private n;
  constructor(int num){
    this.n = num;
  }

  public add(inc = 1){
    this.n = this.n + inc;
  }

}

How do I use it as (1)

let finalNumber = new numbOp(3);
console.log(finalNumber) // Output: 3

How do I use it as (2)

let finalNumber = new numbOp(3).add();
console.log(finalNumber) // Output: 4

How do I use it as (3)

let finalNumber = new numbOp(3).add().add();
console.log(finalNumber) // Output: 5

How do I use it as (4)

let finalNumber = new numbOp(3).add().add(2).toString();
console.log(finalNumber) // Output: "6"

Please, help me out to achieve this. Thanks in advance :)

like image 505
Abhijit Srivastava Avatar asked Dec 29 '18 23:12

Abhijit Srivastava


People also ask

Does TypeScript have optional chaining?

In TypeScript, optional chaining is defined as the ability to immediately stop running an expression if a part of it evaluates to either null or undefined .

How do you do chaining method?

Method Chaining is the practice of calling different methods in a single line instead of calling other methods with the same object reference separately. Under this procedure, we have to write the object reference once and then call the methods by separating them with a (dot.).


1 Answers

You just need to return this from the functions you want to chain

class numbOp {
    private n: number;
    constructor(num: number) {
        this.n = num;
    }

    public add(inc = 1) : this { // annotation not necessary added to address comments
        this.n = this.n + inc;
        return this;
    }
    toString() { 
        return this.n;
    }

}
let finalNumber = new numbOp(3);
console.log(finalNumber + "") // Output: 3
//How do I use it as (2)
let finalNumber2 = new numbOp(3).add();
console.log(finalNumber2 + "") // Output: 4
//How do I use it as (3)
let finalNumber3 = new numbOp(3).add().add();
console.log(finalNumber3 + "") // Output: 5
//How do I use it as (4)
let finalNumber4 = new numbOp(3).add().add(2).toString();
console.log(finalNumber4) // Output: "6"

Edit

Since the console.log part seems to have become more interesting then the chain part in the comments, I'll add the ways to ensure the output in the console is a number:

  1. Override toString and use string coercion to get the string representation of the object
  2. Require a terminator method be called before the display (ie don't forget to call toString when you finish the chain)
  3. Override valueOf and use the unary + operator (this will also make you class usable in binary operations

Code for last option:

class numbOp {
    private n: number;
    constructor(num: number) {
        this.n = num;
    }

    public add(inc = 1) : this { // annotation not necessary added to address comments
        this.n = this.n + inc;
        return this;
    }
    valueOf() { 
        return this.n;
    }

}
let finalNumber2 = new numbOp(3).add();
console.log(+finalNumber2) // Output: 4
console.log(1 + (+finalNumber2)) // Output: 5
console.log(1+(finalNumber2 as any as number)) // Output: 5
like image 108
Titian Cernicova-Dragomir Avatar answered Sep 21 '22 20:09

Titian Cernicova-Dragomir