【问题标题】:Typescript Extend Generic InterfaceTypescript 扩展通用接口
【发布时间】:2020-06-09 09:13:29
【问题描述】:

我想创建一个接口,以便我可以扩展任何打字稿类型以添加​​属性来扩展泛型类型。例如,创建一个如下所示的Confidence<any> 类型:

export interface Confidence<T> extends T{
   confidenceLevel:number
}

然后可以通过以下方式访问它:

const date:Confidence<Date> = new Date();
date.confidenceLevel = .9;

这似乎是不可能的(我觉得它是反模式),但是我可以做到

export type Confidence<T> = T & {
   confidenceLevel:number
}

这似乎完成了我想做的事情,尽管我觉得这样做是在作弊。

我认识到如果我覆盖泛型类型的属性,这种“反向扩展”可能会出现问题,但这是唯一的问题吗?我无法解决这个问题,创建仅添加属性的类型的最佳方法是什么?

【问题讨论】:

    标签: typescript inheritance typescript-generics


    【解决方案1】:

    jcalz 接受的答案扩展:

    如果您想让泛型类型T 可选,您可以从Record&lt;string, unknown&gt; 扩展它并将值设置为Record&lt;string, unknown&gt;

    type Confidence<
      T extends Record<string, unknown> = Record<string, unknown>
    > = T & {
      confidenceLevel: number
    };
    

    然后,如果需要,您将能够在没有任何泛型的情况下使用它:

    interface Bar {
      barLevel: number
    };
    
    const foo: Confidence = { confidenceLevel: 100 };
    const bar: Confidence<Bar> = { confidenceLevel: 100, barLevel: 2 };
    

    【讨论】:

      【解决方案2】:

      有一个长期存在的功能请求,microsoft/TypeScript#2225,它要求能够按照您要求的方式执行 interface Foo&lt;T&gt; extends T {...}。它尚未实施(可能永远不会)。现在你只能用静态已知键创建一个extends 对象类型的接口。未指定的泛型类型参数T 不起作用,因为编译器无法预测它将具有哪些键。

      您应该放心,intersection 是实现此目的的合理方法(请注意,如果您添加的属性与 T 的属性冲突,您不会收到警告,正如您所注意到的)。就是上述功能请求中的suggested解决方案。此外,Object.assign()TypeScript library typings 使用交集来表示将属性添加到现有对象的结果的类型。因此,与Confidence&lt;T&gt; 定义类似

      type Confidence<T> = T & {
        confidenceLevel: number
      }
      

      您可以轻松地编写一个函数来生成其中的一个,如下所示:

      function makeConfidence<T>(x: T, confidenceLevel: number): Confidence<T> {
        return Object.assign(x, { confidenceLevel });
      }
      

      并使用它:

      const x = makeConfidence(new Date(), 0.9); // x is a Confidence<Date>;
      console.log(x.getFullYear()); // 2020
      console.log(x.confidenceLevel); 0.9
      

      看起来不错。好的,希望有帮助;祝你好运!

      Playground link to code

      【讨论】:

      • 感谢您的完整性检查以及关于它是一个请求功能的说明!我想我对界面与类型有点困惑,但我想我会留到另一天。
      • 如果T 是可选类型?像type Confidence&lt;T = never&gt; = T &amp; {...},这将返回一个未定义而不是其余的{...},知道如何解决这个问题吗?
      • 20 分钟后找到了解决方案,我会发布它以防有人需要它
      猜你喜欢
      • 2020-04-09
      • 1970-01-01
      • 2018-07-26
      • 2019-06-08
      • 2020-10-30
      • 2016-07-06
      • 2017-10-21
      • 2018-06-20
      • 2018-04-09
      相关资源
      最近更新 更多