返回作为参数

时间:2018-03-25 09:11:06

标签: javascript typescript types functional-programming typescript2.0

我有一个名为conditional的函数,它接受一个布尔值和一个函数,如果布尔值为true则返回该函数,否则返回一个虚函数。

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

所以,我可以执行这样的代码:

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

但是,当我向条件函数添加类型时,提供给conditional函数的函数的类型签名将丢失。这样就可以在没有TypeScript抱怨的情况下编写像mySqrt("a")这样的代码。

如何向条件函数添加类型,以便保留结果函数的类型?

2 个答案:

答案 0 :(得分:1)

您需要使用泛型类型参数来表示函数的类型:

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

答案 1 :(得分:1)

您可以使用泛型和方法过载签名的组合。

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

当提供重载的方法签名时,编译器将隐藏实际的,更灵活的实现。