node.js - Typescript - 嵌套箭头函数类型
问题描述
我有这个代码用于延迟函数的执行
export type DeferredFunction<T> = () => T | PromiseLike<T>;
export class Deferrable<T> {
protected df: DeferredFunction<T>;
constructor(df: DeferredFunction<T>) {
this.df = df;
}
public async execute(): Promise<T> {
return this.df();
}
}
export const defer = <T>(df: DeferredFunction<T>): Deferrable<T> => new Deferrable<T>(df);
效果很好,我可以运行类似的代码
await defer(() => someFunction('foo', 'bar')).execute();
但我想要做的是以一种DeferredFunction
我可以指定内部函数签名但我无法让它工作的方式输入。在一般情况下,上述方法有效,但是当我想限制参数以使其特定于某种类型的函数时,我没有那种控制。
为清楚起见,我希望能够输入内部函数的输入,例如(例如)
export type InnerDeferredFunction<T> = (a: string, b: number, c: SomeObjectType) => T | PromiseLike<T>
任何帮助将不胜感激!
解决方案
你在说什么“内部功能”?是someFunction
吗?如果是这样,那么 of 的类型DeferredFunction<T>
就没有句柄,因为它是由 的实现调用的函数DeferredFunction<T>
。TypeScript 中没有办法指定“其实现必须调用类型函数的函数(x: string, y: number, z: boolean) => string
”。实现细节不是函数调用签名的一部分。
我可以想象开始解决这个问题的唯一方法是DeferredFunction<T>
接受您要调用的内部函数作为参数,以及调用它的参数列表。这可能不是您要寻找的,但它是类型系统可以表示的最接近的。
像这样的东西:
export type InnerDeferredFunction<T, A extends any[]> = (...args: A) => T | PromiseLike<T>;
export type ZeroArgDeferredFunction<T> = InnerDeferredFunction<T, []>
在这里,我保持A
通用,但您可以将其指定为一些硬编码的参数列表。我已将您的重命名DeferredFunction
为ZeroArgDeferredFunction
明确表示它不需要参数。
但现在Deferrable
需要了解T
and A
:
export class Deferrable<T, A extends any[]> {
protected df: ZeroArgDeferredFunction<T>;
constructor(df: InnerDeferredFunction<T, A>, ...args: A) {
this.df = () => df(...args);
}
public async execute(): Promise<T> {
return this.df();
}
}
您可以看到,您必须通过将内部函数及其参数传递给它来构造一个,而ZeroArgDeferredFunction
是在构造函数内部构建的,而不是传入的。
有不同的定义方式defer()
。它可以是new Deferrable
你拥有它的方式的一个薄包装,或者你可以想象将它拆分,以便 args 出现在第一位:
export const defer = <A extends any[]>(...args: A) => <T>(
df: InnerDeferredFunction<T, A>): Deferrable<T, A> => new Deferrable<T, A>(df, ...args);
然后你可以像这样测试它:
function someFunction(x: string, y: string) {
return (x + y).length;
}
function anotherFunction(x: number, y: number) {
return (x * y).toFixed()
}
const deferFooBar = defer('foo', 'bar');
await deferFooBar(someFunction).execute(); // okay
await deferFooBar(anotherFunction); // error! string is not assignable to number
一旦你调用deferFooBar('foo', 'bar')
了,返回的值将只接受可以使用参数foo
和安全调用的函数'bar'
。这意味着someFunction
将被接受并被anotherFunction
拒绝。
好的,希望有帮助;祝你好运!
推荐阅读
- laravel - 如何验证某人是否是 facebook 用户
- android - 无法删除文件android studio 3.1.3
- wpf - WPF 结束当前线程
- java - 使用 Java 时 IntelliJ 社区中没有错误波浪
- angular - 类型在 Typescript 的服务中显示为未定义
- javascript - 减少或重组 MySQL 查询的对象结果,Javascript
- ansible - 如何在调试时在 Ansible 中指定临时目标?
- java - 为什么“else if”语句的第一个条件总是假的?
- php - 在控制器中应用功能后视图显示不一样
- excel - VBA 程序后 Excel 应用程序无法使用