使用泛型实现和扩展接口

Posted

技术标签:

【中文标题】使用泛型实现和扩展接口【英文标题】:Implementation and extending Interface with generic 【发布时间】:2021-11-07 02:01:25 【问题描述】:

我有一个单调的接口列表。像这样:

interface interface10 
  trackingId: string
  status: string
  payload: 
    code: string
    message: string
  


interface interface11 
  trackingId: string
  status: string
  payload: 
    error: number
    message: string
  


interface interface12 
  trackingId: string
  status: string
  payload: 
    name: string
    surname: string
    age: number
  


interface interface13 
  trackingId: string
  status: string
  payload: 
    name: string
    data: number[]
    labels: Date[]
  

我想用 trackingId、status 和 payload:T 创建一个通用接口。 如何在不创建额外接口的情况下扩展接口并指定有效负载类型? 我只能做到这一点:

interface IBase<T> 
  trackingId: string
  status: string
  payload: T


interface payload1 
  code: string
  message: string


interface interface14 extends IBase<payload1> 
  // Eslint say that i should create at least 1 new property
  what: string


export type interface15 = IBase<
  code: string
  string: string
>

payload 继承和重定义的选项不合适,需要在新接口中指定payload body。如下所示:

interface interface15 extends IBase<interface15> 
  code: string
  message: string


interface interface16 = IBase<
  code: string
  message: string
>

【问题讨论】:

使用interface16,但作为类型别名,如type interface16 = ... 【参考方案1】:

我认为你在正确的轨道上。

我将从概括有效负载开始,这很可能是 json 对象。例如:

type GenericObject =  [key: string]: any;

然后我会像你一样定义 Base ,但是使用 GenericObject 类型进行定义,以便有效负载是一致的,并且无效的有效负载不会意外进入它:

interface IBase<T extends GenericObject> 
  trackingId: string;
  status: string;
  payload: T;

看看你的接口 10-14,除了两次消息之外没有相似之处,所以我会将它们转换为有效负载接口:

interface Payload10 
  code: string;
  message: string;


interface Payload11 
  error: number;
  message: string;


interface Payload12 
  name: string;
  surname: string;
  age: number;


interface Payload13 
  name: string;
  data: number[];
  labels: Date[];

如果您想在代码中使用它们而不使用泛型,您可以将其包装成如下类型:

type Response10 = IBase<Payload10>;

然后在代码中:

class SomeClass 
    base10: IBase<Payload10> | Response10 = 
        trackingId: "1",
        status: "2",
        payload: 
            code: "x",
            message: "y"
        
    

我假设你在这里做某种Response 类型。如果是这样,那么您也可以在IBase 接口中定义Headers,例如:

interface IBase<
  T extends GenericObject,
  Headers extends  [key: string]: string;  = 
> 
  ...
  headers?: Headers;

Headers generic 的末尾分配了,这意味着该generic 是可选的。

【讨论】:

以上是关于使用泛型实现和扩展接口的主要内容,如果未能解决你的问题,请参考以下文章

使用 psalm 扩展接口的泛型

与泛型、接口和扩展混淆

具有类和接口的 Java 泛型 - 一起使用

使用泛型扩展接口的类

ts类泛型接口扩展

如何使泛型 TypeScript 接口从另一个泛型接口扩展?