【问题标题】:infer keyword to get generic type from base classinfer 关键字从基类获取泛型类型
【发布时间】:2018-11-17 23:16:54
【问题描述】:

考虑下面的类

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,而不是联合类型。这可能是一个错误吗?我正在尝试的可能吗?

非常感谢。

【问题讨论】:

    标签: typescript typescript-typings typescript2.0


    【解决方案1】:

    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
    

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

    【讨论】:

    • 您,先生,看来是个真正的打字稿忍者。我想邀请您查看我拥有的a other question,想知道您是否有很好的见解
    • @MauritsMoeys 10x,我会看看,但如果 jcalz 给出答案,我相信他是对的,他是忍者队的一员 :)
    • @MauritsMoeys 看了看,当你第一次发布它时,我实际上看到了这个问题并赞成他的回答。两种解决方案都不是理想的(您的或 jcalz 的),但我认为我们目前无法做得更好。
    • 好的谢谢,小后续问题。你是怎么知道这个话题的答案的?凭经验?还是你在什么地方查到的?如果是后者,我想知道如何/在哪里,因为这意味着我可以更好地“调试”自己
    • @MauritsMoeys 自 v 0.8 以来,我一直在逐个功能地关注 TS,我已经对编译器进行了修改,并且我通常会阅读路线图上的 PR (github.com/Microsoft/TypeScript/wiki/Roadmap)。在这里回答问题也是 TS 经验的重要来源:)。不幸的是,我不能推荐高级 Typescript 主题的一站式资源:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2018-01-13
    • 2020-05-09
    • 1970-01-01
    • 2020-01-29
    • 2011-01-24
    相关资源
    最近更新 更多