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

Mau*_*eys 6 typescript typescript-typings typescript2.0

考虑下面的类

class SomeBaseClass<T extends string | number> {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

type ExtractInner<T> = T extends SomeBaseClass<infer U> ? U : T;
Run Code Online (Sandbox Code Playgroud)

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

type InferredString = ExtractInner<SomeBaseClass<string>>  // InferredString is just type string
Run Code Online (Sandbox Code Playgroud)

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

class StringVersion extends SomeBaseClass<string> {
    ...
}
class NumberVersion extends SomeBaseClass<number> {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

type InferredStringWithExtend = ExtractInnerWithExtend<StringVersion>  // InferredStringWithExtend should be string
type InferredNumberWithExtend = ExtractInnerWithExtend<NumberVersion>  // InferredStringWithExtend should be number
Run Code Online (Sandbox Code Playgroud)

ExtractInner在这种情况下使用将导致简单的string | number,我实际上希望得到stringor number,而不是联合类型。这可能是一个错误吗?我正在尝试的可能吗?

提前谢谢了。

Tit*_*mir 6

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
Run Code Online (Sandbox Code Playgroud)

这种行为的原因是 typescript 类型系统的结构性质,类型结构比继承声明更重要。

  • @MauritsMoeys 10x,我会看看,但如果 jcalz 给出了答案,我相信他是对的,他是忍者小队的一员:) (2认同)
  • @MauritsMoeys 看了一下,我实际上看到了这个问题,并在你第一次发布它时对他的答案进行了投票。这两种解决方案都不理想(您的或 jcalz 的),但我认为我们目前无法做得更好。 (2认同)