0

I have a list of monotonous interfaces. Like this:

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

I want to make one common interface with trackingId, status and payload:T as generic. How can I extend the interface and specify the payload type without creating additional interfaces? I only managed to do this:

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

The option with inheritance and redefinition of the payload is not suitable, it is necessary that the payload body is specified in the new interface. Something like below:

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

interface interface16 = IBase<{
  code: string
  message: string
}>
Mauzzz0
  • 53
  • 1
  • 6

1 Answers1

0

I think you are on the right track.

I would start from generalising payload, which is most likely json object. for example:

type GenericObject = { [key: string]: any};

Then I would define Base like you have done, but using the GenericObject type for defining so that the payloads are consistent and invalid payloads doesn't go into it by accident:

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

Looking at your interfaces 10-14, there are no similarities except message twice, so I would convert them to payload interfaces:

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[];
}

If you want to use them in code without using the generic, you could wrap it in a type like:

type Response10 = IBase<Payload10>;

Then in the code:

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

I assume that you are doing some kind of Response types here. If so, then you can define Headers in IBase interface also, like:

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

The end of Headers generic is assigned {}, which means that the generic is optional.

Polpo
  • 85
  • 6