javascript – When should you use an interface and not a class (and vice versa)?

Question:

When we program with Typescript, we have a concept that does not exist in Javascript: interfaces. In ES6 there are classes, which are syntactic sugar for classical prototyping, but there is no variable typing and nothing like an interface.

One may think that the interfaces are the same as in Java or C #, but I have come across this:

class MiClase {

  constructor( public atributoA: string) {}

  metodoA() {
    //hace algo
  }
}

interface MiInterfaz extends MiClase {
    algo: any;
}

function miFuncion(attr: MiClase) {
  console.log(attr instanceof MiClase);
}

function miFuncion2(attr: MiInterfaz) {
  console.log(attr instanceof MiClase);
}

let a = {
    atributoA: 'hola',
    atributoB: 6,
    metodoA: function () { },
};


miFuncion(a); //false
miFuncion2(a);//false

let b = new MiClase('Una auténtica instancia de MiClase');

miFuncion(b); //true
miFuncion2(b);//compilador marca error, no cumple la interfaz

What's going on here?

  • Why a not give error in the use miFuncion when clearly not the class MiClase ?
  • Why are they interchangeable? The interface extends a class and does not give an error!

Answer:

Why a not give error in the use miFuncion when clearly not the class MiClase ?

a is an anonymous object so it will never be of the instance of type MiClase .

If you try it in javascript you will see that it also returns false :

 function MiClase(valor){ this.atributo = valor; } var aninimo = {atributo: 4}; var instancia = new MiClase(4); console.log(aninimo instanceof MiClase); console.log(instancia instanceof MiClase);

The typescript type checker focuses on how the value / object is defined , not its type. This is called duck typing . Hence, in this case the compiler does not throw you any error:

let a = {
    atributoA: 'hola',
    atributoB: 6,
    metodoA: function () { },
};

miFuncion(a); //false

According to the documentation :

The compiler just checks that at least the properties defined in the interface are present and match the required types.

As a whether it has the properties required by the interface / class MiClase , the compiler allows it.

Why are they interchangeable? The interface extends a class and does not give an error!

As already mentioned, typescript does not focus on the type, but on the way the type is defined, so when an interface extends from a class you are simply adding to the interface the form of the class that it inherits.

In summary, to know when to use an interface or class, the same principles as always are used and thus avoid confusion:

  1. If you need to define a contract to define different behaviors with the same interface or you need to support multiple inheritance, you use an interface.
  2. If you need a specific implementation (such as a factory class), you use a class.
Scroll to Top