Mohideen Imran Khan
Mohideen Imran Khan

Reputation: 833

Preserving type signature when returning a function that was supplied as a parameter

I have a function called conditional that takes in a boolean value and a function, and returns that function if the boolean value is true, or else, returns a dummy function.

function conditional(x, f) {
  if(x)
    return f
  else
    return () => {}
}

So, I can execute code like this:

let mySqrt = conditional(true, Math.sqrt)
let add = (x, y) => x + y
let myAdd = conditional(true, add)

However, when I add types to the conditional function, the type signature of the function supplied to the conditional function is lost. And this makes it possible to write code like mySqrt("a") without TypeScript complaining.

How do I add types to the conditional function such that the type of the resulting function is preserved?

Upvotes: 2

Views: 61

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250136

You need to use a generic type parameter to represent the type of the function:

function conditional<T extends (...args: any[]) => any>(x: boolean, f: T): T {
    if (x)
        return f;
    else
        return (() => { }) as any; // we need an assertion here to make the empty function compatible with T
}

// Usage
let mySqrt = conditional(true, Math.sqrt); //mySqrt will be of type (x: number) => number
let add = (x: number, y: number) => x + y;
let myAdd = conditional(true, add); // myAdd will be of type (x: number, y: number) => number

Upvotes: 1

Tao
Tao

Reputation: 2242

You can use a combination of generics and method overload signatures.

function conditional<T extends Function>(x: true, f: T): T;
function conditional<T extends Function>(x: false, f: T): () => {};
function conditional<T extends Function>(x: boolean, f: T) {
  if(x)
    return f
  else
    return () => {}
}

let mySqrt = conditional(true, Math.sqrt)
mySqrt('a') // error

When providing overloaded method signatures the compiler will hide the actual, more flexible implementation.

Upvotes: 1

Related Questions