【问题标题】:How do I define and call a generic function parameter in Typescript?如何在 Typescript 中定义和调用泛型函数参数?
【发布时间】:2020-09-25 17:24:16
【问题描述】:

我正在 Typescript 中寻找与 Function.prototype.call 等效的单参数类型安全。

这不起作用,因为F 缺少正确的约束(也许):

function call<F,A>(f: F, arg: A) {
  return f(arg);
}

因此,Typescript 抱怨“此表达式不可调用。类型 'unknown' 没有调用签名。”

如何使F 可调用?如何管理 call 以使其返回类型为 F

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    正如您所说,您需要添加一个约束,以便它可以调用。一个选项可能如下所示:

    function call<F extends Function,A>(f: F, arg: A) {
      return f(arg);
    }
    

    通用约束:https://www.typescriptlang.org/docs/handbook/generics.html#generic-constraints

    如果您想提供更强的类型安全性,一种方法可能如下所示。

    type Parameter<T> = T extends (arg: infer T) => any ? T : never;
    
    
    function call<F extends (arg: any) => any>(f: F, arg: Parameter<F>): ReturnType<F> {
      return f(arg);
    }
    
    const fn = (input: number): number => input * 2;
    
    const result = call(fn, 2) // Valid
    const result2 = call(fn, "2") // Argument of type '"2"' is not assignable to parameter of type 'number'.(2345)
    const result3 = call(fn, false) // Argument of type 'false' is not assignable to parameter of type 'number'.(2345)
    
    const badFn = (input: number, options: {}): number => input * 2;
    
    const result4 = call(badFn, 2) // Argument of type '(input: number, options: {}) => number' is not assignable to parameter of type '(arg: any) => any'.(2345)
    

    这为F 定义了一个更严格的约束,表示它必须是一个只接受一个参数的函数。然后从该函数中推断出参数。您也可以使用 Parameters&lt;F&gt;[0],因为 Parameters 是 Typescript 提供的实用程序类型。 ReturnType 是另一种推断F 的返回类型的实用程序类型,可以用作call 的返回类型。

    【讨论】:

    • 啊,Function 是否在 Typescript 文档中有所描述?并且:call 现在返回 any。我可以让它类型安全吗?
    • @mkluwe 我更新了一个类型安全性更强的示例
    • 好的,已接受答案。如果你不介意的话,我做了一些小动作来避免指定返回类型。
    猜你喜欢
    • 2023-01-12
    • 1970-01-01
    • 2019-01-23
    • 2020-12-27
    • 2020-11-10
    • 1970-01-01
    • 2020-01-23
    • 2019-09-19
    • 2018-09-15
    相关资源
    最近更新 更多