推断关键字以从基类获取泛型

时间:2018-11-17 23:16:55

标签: typescript typescript-typings typescript2.0

考虑以下课程

class SomeBaseClass<T extends string | number> {
    ...
}

以及以下使用infer关键字的条件类型

type ExtractInner<T> = T extends SomeBaseClass<infer U> ? U : T;

这样,我们可以像这样(或多或少来自文档)提取SomeBaseClass中使用的通用类型

type InferredString = ExtractInner<SomeBaseClass<string>>  // InferredString is just type string

在我稍微更高级的情况下,情况如下

class StringVersion extends SomeBaseClass<string> {
    ...
}
class NumberVersion extends SomeBaseClass<number> {
    ...
}

如何定义类型ExtractInnerWithExtend,使其等同于ExtractInner?即:

type InferredStringWithExtend = ExtractInnerWithExtend<StringVersion>  // InferredStringWithExtend should be string
type InferredNumberWithExtend = ExtractInnerWithExtend<NumberVersion>  // InferredStringWithExtend should be number

在这种情况下使用ExtractInner只会得到string | number,我实际上希望得到stringnumber,而不是联合类型。这可能是错误吗?我正在尝试的可能吗?

非常感谢。

1 个答案:

答案 0 :(得分:3)

ExtractInner将在一种情况下处理类型的派生版本:您实际上以某种方式在基类中使用了类型

class SomeBaseClass<T extends string | number> {

  private value!: T

  // Any of these will also work
  //value!: T
  //m(v:T): void {}
  //m(): T { return null as any }
}

type ExtractInner<T> = T extends SomeBaseClass<infer U> ? U : T;


class StringVersion extends SomeBaseClass<string> {}
class NumberVersion extends SomeBaseClass<number> {}

type InferredStringWithExtend = ExtractInner<StringVersion>  // string
type InferredNumberWithExtend = ExtractInner<NumberVersion>  // number

此行为的原因是打字稿类型系统的结构性质,类型结构比继承声明更重要。