17

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 :)

1 Answer 1

10

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
Sign up to request clarification or add additional context in comments.

8 Comments

console.log(finalNumber) Won't work - that will return an object, not the number (nor a string), pretty sure OP's desired output is impossible without a toString call on each
@AbhijitSrivastava Either use a terminating call after the end of each chain to return the number itself, or coerce the result to a string every time
@AbhijitSrivastava you can let the compiler infer it or use this as the return type if you want to be explicit
@AbhijitSrivastava You could override valueOf instead of toString, that way you can use the unary + operator while logging the object: console.log(+finalNumber). Using +finalNumber instead of finalNumber + "" is clearer because you are logging the numeric value of finalNumber.
@ibrahimmahrir nice idea, i'll add it to the answer as an option
|

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.