首页 > 解决方案 > 使用泛型实现和扩展接口

问题描述

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

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
}>

带有继承和重新定义有效负载的选项不合适,必须在新接口中指定有效负载主体。如下所示:

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

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

标签: typescriptgenericsinheritancetypescript-genericsinterface-implementation

解决方案


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

我将从概括有效负载开始,这很可能是 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这里做某种类型。如果是这样,那么您也可以HeadersIBase接口中定义,例如:

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

Headers generic 的末尾被赋值{},这意味着泛型是可选的。


推荐阅读