根据类型参数推断出打字稿类型

时间:2018-11-23 15:06:33

标签: typescript type-inference

我不明白为什么在以下涉及从类型参数进行推断的情况下,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,因此您认为编译器可以从P的定义中推断出RValueDialog,但事实并非如此。

我可以通过手动指定类型来解决此问题,但这很丑陋。我也可以通过使PR相同来修复它,但这不是我想要的功能。

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

1 个答案:

答案 0 :(得分:0)

您可以使用条件类型从基本类型中提取类型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