Typescript 扩展通用接口

Posted

技术标签:

【中文标题】Typescript 扩展通用接口【英文标题】:Typescript Extend Generic Interface 【发布时间】: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

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

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

【问题讨论】:

【参考方案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 分钟后找到了解决方案,我会发布它以防有人需要它

以上是关于Typescript 扩展通用接口的主要内容,如果未能解决你的问题,请参考以下文章

具有通用方法的Typescript接口

打字稿:使用特定的扩展接口来满足通用的“扩展”类型参数?

TypeScript基础教程

TypeScript基础教程

TypeScript基础教程

打字稿通用和扩展