AWS
如何确保function higherOrderFunction<P extends any[], R>(anyFunction: (...a: P) => R) {
return (...args: P) => {
anyFunction(...args); // anyFunction = lowerOrderFunction
};
}
function lowerOrderFunction(name: string) {
return '';
}
const higherOrderFunctionWithLowerOrderFunction = higherOrderFunction(lowerOrderFunction);
higherOrderFunctionWithLowerOrderFunction('x');
具有anyFunction
类型?
这必须是传递给HigherOrderFunction的泛型函数(此处泛指“任何函数”),而不仅仅是上面的示例void
足以添加{{1} }
答案 0 :(得分:4)
TypeScript不希望您执行此操作,请参见the FAQ。无论何时需要返回void
的函数,都可以使用返回非void
值的函数。在TypeScript中,返回void
的意思是“您不应该尝试使用此函数的返回值”,而不是“此函数实际上不返回值”。因此,此问题的最常规答案是您无需强制实施此类限制;如果anyFunction
返回一个值,它将被忽略,应该没问题。
如果您真的想弯曲规则以便TypeScript强制执行该限制,那么您可以做的一件事是:
function higherOrderFunction<P extends any[]>(anyFunction: (...a: P) => undefined | void) {
return (...args: P) => { anyFunction(...args); };
}
通过指定undefined | void
表示您将接受undefined
返回值(应该可以,对吗?),否则将返回一个不返回的函数(使用void
结合起来似乎在这里规避了编译器的“任何值都可以”的逻辑):
higherOrderFunction(() => 1); // error, number is not undefined
higherOrderFunction(() => undefined); // okay
higherOrderFunction(() => console.log("this is void returning")); // okay
或者,如果您想使编译器甚至拒绝undefined
返回函数,则可以使用一个通用的签名来推断返回类型,然后使事情不起作用,除非它推断的类型为void
:
function higherOrderFunction<P extends any[], R>(
anyFunction: (...a: P) => R & (void extends R ? void : never)
) {
return (...args: P) => { anyFunction(...args); };
}
如果(void extends R ? void : never)
为void
,则类型R
的值为void
,否则为never
。这样您就会得到以下行为:
higherOrderFunction(() => 1); // error, number is not never
higherOrderFunction(() => undefined); // error, undefined is not never
higherOrderFunction(() => console.log("this is void returning")); // okay
这些方法“起作用”是因为它们对示例用例施加了限制,但是可能存在边缘情况。最明显的边缘情况是以下代码与higherOrderFunction
无关,并且不会生成警告:
const thisIsAllowed: () => void = () => 1; // okay
毕竟,非无效返回函数可以分配给无效返回函数。现在,编译器将thisIsAllowed
视为返回void
的函数;它已经忘记了1
。
因此,无论如何定义higherOrderFunction()
以便“要求” void
返回,这里都不会出现错误:
higherOrderFunction(thisIsAllowed); // no error
根据您的用例,这可能对您来说是个大难题。
我认为最好的做法可能是接受TypeScript的观点,即void
返回类型的意思是“忽略返回的任何值”而不是“不返回任何值”,然后继续。也许上述规则折弯方法仍然对您有用,但是您不应该依赖它们来禁止返回值的函数。
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:0)
只需更改传递给参数的anyFunction的返回类型
function higherOrderFunction<P extends any[], R>(anyFunction: (...a: P) => void) {
return (...args: P) => {
anyFunction(...args); // anyFunction = lowerOrderFunction
};
}
function lowerOrderFunction(name: string) {
return '';
}
const higherOrderFunctionWithLowerOrderFunction = higherOrderFunction(lowerOrderFunction);
higherOrderFunctionWithLowerOrderFunction('x');