【问题标题】:Typescript type inference from type parameters来自类型参数的 Typescript 类型推断
【发布时间】:2019-04-26 04:53:30
【问题描述】:

我不明白为什么 Typescript 在以下涉及类型参数推断的情况下无法正确推断类型。 (这个问题与TypeScript type inference issue 类似,但情况有些不同。答案可能是一样的,但我只是不走运!)

// A base class for a dialog taking parameter of type P
// and returning result of type R.
class BaseDialog<P, R> { p: P; r: R; }

class ValueDialog extends BaseDialog<string, number> {}

// A function that shows the dialog
show<T extends BaseDialog<P, R>, P, R>(dlg: Type<T>, param: P): Promise<R> {}

注意:为了简化方法签名,我使用的是 Angular 的Type

export interface Type<T> extends Function {
  new (...args: any[]): T;
}

现在,当我调用方法show,如下,R类型没有正确推断:

show(ValueDialog, "name").then(r => console.log(r));

编译器推断:

T = ValueDialog
P = string
R = {}

由于T 被正确推断,您可能认为编译器可以从ValueDialog 的定义推断PR,但事实并非如此。

当然,我可以通过手动指定类型来解决这个问题,但这非常难看。我也可以通过使PR 相同来修复它,但这不是我想要的功能。

如何定义show() 以便正确推断R

【问题讨论】:

标签: typescript type-inference


【解决方案1】:

您可以使用条件类型从基本类型中提取类型R 参数。您需要以某种方式使用 R 类型才能使其工作:

export interface Type<T> extends Function {
    new (...args: any[]): T;
}
class BaseDialog<P, R> {
    value: R //we need to use R in some  way for the parameter to make a difference
}

class ValueDialog extends BaseDialog<string, number> {}


type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never; 
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;

show(ValueDialog, "name").then(r => console.log(r)); // r is now string

【讨论】:

  • 这行得通!我可以(大部分)遵循 ExtractResult 类型,但我自己永远无法想出这个!我来自另一个链接,这是从类型参数推断类型的唯一方法。感谢您的帮助!
猜你喜欢
  • 2016-12-05
  • 1970-01-01
  • 2021-12-22
  • 2018-08-28
  • 2018-12-13
  • 2020-03-11
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多