How to declare 2 interfaces with the same body?

Viewed 486

I have a base interface IInput and extended from it 3 interfaces IType1Input, IType2Input and IType3Input. After a few business changes to Type2(), IType2Input is now the same as IInput, but for consistency I don't want only Type2() to use IInput instead of an extended interface. I tried to do this:

    interface IType2Input extends IInput {}

ESLint then warned me about no-empty-interface. If I don't want to disable this rule, is there a way to declare IType2Input as the same interface as IInput?

2 Answers

Try using a type instead of an interface until that interface is different. Note that under the hood interfaces and types are the same.

type IType2Input = IInput;

I know you're not looking for this suggestion, so feel free to skip the following section. This is mostly for future readers who come upon this question/answer pair.


I'd say that the no-empty-interface ESLint rule is not appropriate for your use case, and you really should disable the rule for the line in question without necessarily disabling it for your whole code base.

The documentation for the rule says "an empty interface is equivalent to its supertype ... [and therefore it] can be omitted." When you write

interface IType2Input extends IInput {} // linter warning!

and get a linter warning, the rule wants you to replace all references to IType2Input with IInput because IType2Input is redundant. But you don't want to do this. If you find a way to rewrite your code so that two equivalent interfaces named IType2Input and IInput exist without triggering the linter warning, you'd still be violating the spirit of the rule if not the letter.

Instead of trying to figure out how to circumvent the rule with syntax that might possibly be more complicated than an empty interface, you could just disable the rule for the one declaration, and comment it to let people know what you're doing and why:

// IType2Input is intentionally empty. It happens not
// to have more properties than IInput, but this may
// change in the future, and it helps to have a Type2-specific
// interface that people can use.  Therefore the no-empty-interface
// rule is not appropriate for this declaration:

// eslint-disable-next-line no-empty-interface
interface IType2Input extends IInput { }

From here on out I'll assume that you don't want to do this.


One way to circumvent the rule is to use the syntax for extending multiple interfaces, but the "multiple" interfaces are both just IInput:

interface IType2Input extends IInput, IInput { } // no error

This manages not to trigger the linter rule. But, as you said, it's basically a hack. And anyone who sees this code later would probably refactor it to just extends IInput, which would bring you back to the original problem.


Playground link to code

Related