typescript - 为泛型函数特化一个类型

标签 typescript generics typescript-generics

给出这个定义:

declare function foo<T>(): { bar: T }

// <T>() => { bar: T }
type Foo = typeof foo;

如何根据类型为泛型函数提供特化?

我想要实现的是能够做这样的事情:

// { bar: number }
type FooResult = ReturnType<Foo<number>>;

但是 TypeScript 提示 Foo 本身不是通用的——它键入的函数是通用的。

最佳答案

TypeScript 并不真正支持您需要从 ReturnType 获取的那种高阶类型... 这是一个 known design limitation .因此,您所拥有的只是各种解决方法。以下是我能想到的:

  • 手动完成。这本质上是一个非答案,但可能是最好的前进方式,因为它不依赖于任何奇怪的类型系统技巧:

    type FooResult<T> = { bar: T };
    type FooResultNumber = FooResult<number>; // {bar: number}
    
  • 假装调用foo()并得到它的结果。 TypeScript 不支持 arbitrary type queries , 所以 type FooResult = typeof foo<number>()不幸的是不编译。以下代码尽可能接近:

    const __dummy = (true as false) || foo<number>();
    type FooResultNumber = typeof __dummy; // {bar: number}
    

    这会在您的运行时代码中引入一个虚拟变量。 (true as false) || expression构造使用 type assertion欺骗编译器。编译器认为你在​​做 false || expression ,其类型将与 expression 的类型相同.你在运行时真正做的是 true || expression哪个短路,返回true从未评估expression .这意味着 foo()尽管在代码中,但在运行时永远不会被调用。

  • 假装调用foo()的另一种方式是一个虚拟类......你永远不会实例化这个类,但它让编译器推理类型:

    class __FooRunner<T> {
      result = foo<T>();
    }
    type FooResult<T> = __FooRunner<T>["result"];
    type FooResultNumber = FooResult<number>; // {bar: number}
    

    同样,这会在您的运行时代码中放入一些垃圾,根据您的用例,这可能会或可能不会被接受。

好的,希望对你有帮助;祝你好运!

Link to code

关于typescript - 为泛型函数特化一个类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57142802/

相关文章:

c# - "where"c sharp 类声明中的关键字

mongodb - 带有 MongoDB findOne 方法的 typescript 不适用于泛型

javascript - 在构造函数中使用 FormBuilder 是一种不好的做法吗?

c# - 在 C# 4.0 中,是否可以从泛型类型参数派生类?

typescript - 使用 Angular2 从 url 中检索哈希片段

java - 带有map java的通用方法

typescript - 如何使用 TypeScript 进行类型化元编程?

TypeScript 通用默认类型与上下文类型

angular - 如何访问效果中的状态树? (@ngrx/效果 2.x)

Typescript 无法弄清楚通用性