Typescript interface are not overloading / merging subsequent interface fields

134 views Asked by At

I know that interfaces in typescript allow us to merge different types. When i tried to do so, i am getting error while transpiling the script.

Here is my buggy interface

export interface StoreConfig extends Document, TimeStamps {
  type: 'webhook'
  metadata: {
    endpoint: string
    method: HttpMethod
    secret: string
    event: string | string[]
  }
}

export interface StoreConfig extends Document, TimeStamps {
  type: 'buylink'
  metadata: {
    prodId: string
    key: string
    expire: Date
  }
}

export interface StoreConfig extends Document, TimeStamps {
  type: 'paymentmethod'
  metadata: {
    apiKey: string
    mode: string
    whsecret: string
  }
}

I am getting this error on transpiling ts script

Subsequent property declarations must have the same type.  Property 'type' must be of type '"webhook"', but here has type '"buylink"'.

PS: I have seen many libraries (for example: nodemailer, inquirer) are loading typings based on some flag or condition.

1

There are 1 answers

11
captain-yossarian from Ukraine On BEST ANSWER
/**
 * Simplified example
 */

export interface StoreConfig extends Document {
    type: 'webhook'

}

export interface StoreConfig extends Document {
    type: 'buylink'

}

export interface StoreConfig extends Document {
    type: 'paymentmethod'
}

/**
 * This is how it works
 * 1) 
 */

export interface A {
    type: 'buylink'

}

export interface A {
    payload: number
}

type O = keyof A // type | payload

/**
 * Because you can't do smth like that
 */

type CustomType = 'buylink' & 'webhook' // never

/**
 * Above type is never because it is irrepresentable
 * Please treat merging as & operator on high level
 */

Demo1

What you need to do is to make a union type. Just like @ritaj wrote in his comment:

export interface StoreConfig1 extends Document {
    type: 'webhook'

}

export interface StoreConfig2 extends Document {
    type: 'buylink'

}

export interface StoreConfig3 extends Document {
    type: 'paymentmethod'
}

type StoreConfig = StoreConfig1 | StoreConfig2 | StoreConfig3

Demo2