【问题标题】:Creating a generic proxy function in TypeScript在 TypeScript 中创建通用代理函数
【发布时间】:2021-09-05 21:55:09
【问题描述】:

假设我想创建一个这样的通用代理函数:

type Callback<F extends (...args: any) => any> = F extends (...args: infer P) => infer R 
? (
    P extends [] ? (onComplete?: (result: R) => void) => void : (parameters: P, onComplete?: (result: R) => void) => void
)
: never;

function  createCallback<P extends unknown[], R, F extends (...args: P) => R>(func: F): Callback<F> {
    return (parameters?: P | ((result: R) => void), onComplete?: (result: R) => void ): void => {
        if (Array.isArray(parameters)) {
            R result = func(...parameters);
            if (onComplete) {
                onComplete(result);
            }
        } else if (typeof parameters === "function") {
            R result = func();
            parameters(result);
        }
    }
}

如果传递的函数接受一些参数,那么返回的函数应该有一个签名(参数:[

在 TypeScript 中可以做到这一点吗?上面的代码无法编译,并显示返回的函数不可分配给回调类型的错误消息。

【问题讨论】:

  • 请分享没有 wyntax 错误的示例。 R result = func(...parameters) - 不允许的语法

标签: typescript typescript-generics


【解决方案1】:

如果您确信 createCallback 会做它应该做的事情,那么这样做是合理的
return (...) as any as Callback&lt;F&gt;

另外,这让编译器很高兴 (playground)

type Callback<F extends (...args: any) => any> = F extends (...args: infer P) => infer R
    ? (...args: PossibleArguments<P, R>) => void
    : never;

type PossibleArguments<P, R, OnComplete = (result: R) => void> =
    [] extends P
    ? ([] | [onComplete: OnComplete])
    : ([parameters: P] | [parameters: P, onComplete: OnComplete])
// or
type PossibleArguments<P, R> = [...parameters: [] extends P ? [] : [parameters: P], onComplete?: (result: R) => void]

function createCallback<P extends unknown[], R>(func: (...args: P) => R): Callback<(...args: P) => R> {
    return ((...args: PossibleArguments<P, R>): void => {
        // ...
    })
}

它使回调的签名变得丑陋,但调用它们时自动完成仍然有效

【讨论】:

  • 您可以使用optional tuple elementsPossibleArguments 简化为[] extends P ? [onComplete?: OnComplete] : [parameters: P, onComplete?: OnComplete]。您甚至可以将其进一步简化为[...parameters: [] extends P ? [] : [parameters: P], onComplete?: (result: R) =&gt; void]
  • @cherryblossom 这更好,它甚至使提示和自动完成看起来“正常”。然而,在没有类型断言的情况下编写 createCallback 的主体似乎是不可能的(?),此时 OP 的解决方案可能更有意义
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2020-01-20
相关资源
最近更新 更多