我有一个高阶函数,它通过在线检查包装函数,我正在尝试为其编写类型签名,但我无法弄明白。这是我到目前为止所得到的:
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) =>
如何正确注释?
答案 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);
};