Typescript 扩展通用接口

Bob*_*ose 5 inheritance typescript typescript-generics

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

export interface Confidence<T> extends T{
   confidenceLevel:number
}
Run Code Online (Sandbox Code Playgroud)

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

const date:Confidence<Date> = new Date();
date.confidenceLevel = .9;
Run Code Online (Sandbox Code Playgroud)

这似乎不可能(我感觉这是反模式),但是我可以做

export type Confidence<T> = T & {
   confidenceLevel:number
}
Run Code Online (Sandbox Code Playgroud)

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

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

jca*_*alz 11

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

您应该放心,交集是实现此目的的合理方法(需要注意的是,如果您添加的属性与 的属性冲突,正如您所注意到的,您不会收到警告T)。这是上述功能请求中建议的解决方案。此外,TypeScript 库类型使用Object.assign()交集来表示向现有对象添加属性的结果的类型。因此,Confidence<T>定义如下

type Confidence<T> = T & {
  confidenceLevel: number
}
Run Code Online (Sandbox Code Playgroud)

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

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

并使用它:

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

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

Playground 代码链接