typescript - 如何确保传递给高阶函数的泛型函数具有 void 返回类型?
问题描述
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
会有void
类型?
这必须用于传递给higherOrderFunction的泛型函数(泛型在这里表示“任何函数”),而不仅仅是lowerOrderFunction
上面的示例足以添加:void
解决方案
TypeScript 不希望您这样做,请参阅常见问题解答。返回非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
if R
is 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
毕竟,非 void-returning 函数可以分配给 void-returning 函数。现在编译器将thisIsAllowed
其视为void
-returning 函数;它已经忘记了一切1
。
因此,无论如何higherOrderFunction()
定义以“要求”void
返回,这里都不会出错:
higherOrderFunction(thisIsAllowed); // no error
根据您的用例,这可能会破坏您的交易。
我认为最好的做法可能是接受 TypeScript 的观点,即void
返回类型意味着“忽略返回的任何值”而不是“不返回任何值”,然后继续前进。也许上面的规则弯曲方法仍然对你有用,但你不应该依赖它们来禁止返回值的函数。
好的,希望有帮助;祝你好运!
推荐阅读
- python-3.x - 用数组评估 sympy 多项式
- java - 如何处理 ArrayIndexOutofBoundsException?
- python-3.x - 使用 Python 在灰度 CT 图像中隔离头部
- docker - 只查看 `docker service ps xxx` 结果中的 ERROR 列?
- gcloud - 将长时间运行的高计算应用程序部署到 GCP 的最佳方式
- java - 如何在 MongoDB 中使用投影和过滤器区分查询?
- ruby-on-rails - 从数组到二维数组,除以 2 个值
- javascript - BMI计算程序
- swift - 无法从 ios 13 中的 url 视频生成缩略图
- python - python中列表中最后6个值的最小值