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<string, unknown>
扩展它并将值设置为Record<string, unknown>
。
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<T> extends T ...
。它尚未实施(可能永远不会)。现在你只能用静态已知键创建一个extends
对象类型的接口。未指定的泛型类型参数T
不起作用,因为编译器无法预测它将具有哪些键。
您应该放心,intersection 是实现此目的的合理方法(请注意,如果您添加的属性与 T
的属性冲突,您不会收到警告,正如您所注意到的)。就是上述功能请求中的suggested解决方案。此外,Object.assign()
的 TypeScript library typings 使用交集来表示将属性添加到现有对象的结果的类型。因此,与Confidence<T>
定义类似
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<T = never> = T & ...
,这将返回一个未定义而不是其余的...
,知道如何解决这个问题吗?
20 分钟后找到了解决方案,我会发布它以防有人需要它以上是关于Typescript 扩展通用接口的主要内容,如果未能解决你的问题,请参考以下文章