Merge Two Interfaces

Typescript

Typescript Problem Overview


Seeking confirmation or clarification

If I have two interfaces. What is the "proper" way to create a merge of those two interfaces?

IFoo {
  // some stuff
}


IBar {
  // some stuff
}


IFooBar extends IFoo, IBar {
 // Empty
}

It works but it feels weird, like I am doing it wrong with the empty IFooBar.

Am I doing this correctly?

I also noticed that this also works:

type IFooBar = IFoo & IBar;

I have an illogical aversion to using type yet, it is much cleaner.

Typescript Solutions


Solution 1 - Typescript

This article explains the relation between interfaces and type aliases very well, this part is focused on small differences between them.

Both

interface IFooBar extends IFoo, IBar {}

and

type IFooBar = IFoo & IBar;

are common ways to do this and will behave identically in most cases. Since type takes less characters to type, it could be chosen for that reason.

The inconsistency that is caused by mixed interface and type shouldn't be a problem; they are just suitable features to achieve the goal. If const BarClass = FooClass does the job, class BarClass extends FooClass {} shouldn't be preferred just because its consistently uses class everywhere (this example is used for illustrative purposes, there's a considerable difference between these approaches).

Even though interface and type can behave similarly, there is a difference in case of merged interface (also covered in linked article). This will work:

interface FooBar extends IFoo, IBar {}
class FooBar { ... }

And this will cause type error:

type FooBar = IFoo & IBar;
class FooBar { ... }

Solution 2 - Typescript

If you're wanting to merge 2 interfaces which contain members more than 1 level deep:

export interface TypeOne  {
  one: {
    two: {
      hello: string;
    }[]
  }
}

export type TypeTwo = {
  one: {
    two: {
      world: string;
    }[]
  }
} & TypeOne;

const x: TypeTwo;
x.one.two[0]. // autocomplete options are 'hello' / 'world'

Solution 3 - Typescript

I think there it is ok, or not ok relating to what meaning of the merged interface. If IFooBar is a new entity from perspective of object-oriented design, then empty interface is all right. But if there is no such entity, but you want just merge some unrelated interfaces (for some hacky code) - then just use IFoo & IBar in variable type definition, or type for shortening this.

It's just my opinion as programmer, that came from object oriented languages like C++ and C#.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser9298624View Question on Stackoverflow
Solution 1 - TypescriptEstus FlaskView Answer on Stackoverflow
Solution 2 - TypescriptStephen PaulView Answer on Stackoverflow
Solution 3 - TypescriptPavelView Answer on Stackoverflow