如何键入函数将任何函数作为参数?

时间:2017-06-22 07:38:02

标签: typescript

我有一个高阶函数,它通过在线检查包装函数,我正在尝试为其编写类型签名,但我无法弄明白。这是我到目前为止所得到的:

const preventOffline = <T extends Function>(fn: T): T =>
  function() {  // Error: Type '() => any' is not assignable to type 'T'.
    if (!window.navigator.onLine) {
      alert("Sorry, please retry when you're online.");
      return undefined;
    }
    return fn.apply(this, arguments);
  };

我也尝试了这个,由于某种原因,我错误地说T已声明但从未使用过。

export const preventOfflineHOF = <T, U>(fn: (T) => U): ((T) => U | undefined) =>

如何正确注释?

2 个答案:

答案 0 :(得分:1)

签名表示应该返回传入的相同类型的函数,但编译器无法断言是这种情况。

如果你有一个你期望的特定功能签名,那么你可以这样做:

const preventOffline = (fn: (p1: string, p2: number) => boolean): (p1: string, p2: number) => boolean => 
    function (p1: string, p2: number) {
        return false;
}

编译器不会抱怨 但是因为你想要允许所有函数,你只需要通过转换为any告诉编译器你知道你在做什么:

const preventOffline = <T extends Function>(fn: T): T =>
    function () {
        if (!window.navigator.onLine) {
            alert("Sorry, please retry when you're online.");
            return undefined;
        }
        return fn.apply(this, arguments);
} as any;

另一种选择是删除泛型并只接受Function

const preventOffline = (fn: Function): Function =>
    ...
};

但是你丢失了传入函数的类型,而preventOffline只是Function

答案 1 :(得分:-2)

const preventOffline = <T extends Function>(fn: () => T): T =>
  function() {
    if (!window.navigator.onLine) {
      alert("Sorry, please retry when you're online.");
      return undefined;
    }
    return fn.apply(this, arguments);
 };