Is there a way to create interfaces in ES6 / Node 4?

ES6 is fully available in Node 4. I was wondering if it includes the concept of an interface for defining method contracts, as in MyClass implements MyInterface .

I can't find much with my Googling, but maybe there is a good trick or workaround.

+99
javascript ecmascript-6 interface
Sep 17 '15 at 9:27
source share
5 answers

Interfaces are not part of ES6, but there are classes.

If you really need them, you should take a look at TypeScript, which supports them .

+79
Sep 17 '15 at 9:33
source share

In debiasej's comments, the article below is written explaining more about design patterns (based on interfaces, classes):

http://loredanacirstea.imtqy.com/es6-design-patterns/

Designing book templates in javascript can also be useful for you:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Design pattern = classes + interface or multiple inheritance

Example factory template in ES6 JS (to run: node example.js):

 "use strict"; // Types.js - Constructors used behind the scenes // A constructor for defining new cars class Car { constructor(options){ console.log("Creating Car...\n"); // some defaults this.doors = options.doors || 4; this.state = options.state || "brand new"; this.color = options.color || "silver"; } } // A constructor for defining new trucks class Truck { constructor(options){ console.log("Creating Truck...\n"); this.state = options.state || "used"; this.wheelSize = options.wheelSize || "large"; this.color = options.color || "blue"; } } // FactoryExample.js // Define a skeleton vehicle factory class VehicleFactory {} // Define the prototypes and utilities for this factory // Our default vehicleClass is Car VehicleFactory.prototype.vehicleClass = Car; // Our Factory method for creating new Vehicle instances VehicleFactory.prototype.createVehicle = function ( options ) { switch(options.vehicleType){ case "car": this.vehicleClass = Car; break; case "truck": this.vehicleClass = Truck; break; //defaults to VehicleFactory.prototype.vehicleClass (Car) } return new this.vehicleClass( options ); }; // Create an instance of our factory that makes cars var carFactory = new VehicleFactory(); var car = carFactory.createVehicle( { vehicleType: "car", color: "yellow", doors: 6 } ); // Test to confirm our car was created using the vehicleClass/prototype Car // Outputs: true console.log( car instanceof Car ); // Outputs: Car object of color "yellow", doors: 6 in a "brand new" state console.log( car ); var movingTruck = carFactory.createVehicle( { vehicleType: "truck", state: "like new", color: "red", wheelSize: "small" } ); // Test to confirm our truck was created with the vehicleClass/prototype Truck // Outputs: true console.log( movingTruck instanceof Truck ); // Outputs: Truck object of color "red", a "like new" state // and a "small" wheelSize console.log( movingTruck ); 
+9
Dec 19 '15 at 20:37
source share

This is my solution to the problem. You can "implement" multiple interfaces by overriding one interface with another.

class MyInterface {

 //Declare your JS doc in the Interface to make it acceable while writing the Class and for later inheritance/** * Gives the sum of the given Numbers * @param {Number} a The first Number * @param {Number} b The second Number * @return {Number} The sum of the Numbers */sum(a, b) { this._WARNING('sum(a, b)'); }//delcare a warning generator to notice if a method of the interface is not overridden//Needs the function name of the Interface method or any String that gives you a hint ;) _WARNING(fName='unknown method') { console.warn('WARNING! Function "'+fname+'" is not overridden in '+this.constructor.name); } } class MultipleInterfaces extends MyInterface {//this is used for "implement" multiple Interfaces at once/** * Gives the square of the given Number * @param {Number} a The Number * @return {Number} The square of the Numbers */square(a) { this._WARNING('square(a)'); } } class MyCorrectUsedClass extends MyInterface {//You can easy use the JS doc declared in the interface/** @inheritdoc */sum(a, b) { return a+b; } } class MyIncorrectUsedClass extends MyInterface {//not overriding the method sum(a, b) } class MyMultipleInterfacesClass extends MultipleInterfaces {//nothing overriden to show, that it still works } let working = new MyCorrectUsedClass(); let notWorking = new MyIncorrectUsedClass(); let multipleInterfacesInstance = new MyMultipleInterfacesClass();//TEST IT console.log('working.sum(1, 2) =', working.sum(1, 2));//output: 'working.sum(1, 2) = 3' console.log('notWorking.sum(1, 2) =', notWorking.sum(1, 2));//output: 'notWorking.sum(1, 2) = undefined'//but also sends a warn to the console with 'WARNING! Function "sum(a, b)" is not overridden in MyIncorrectUsedClass' console.log('multipleInterfacesInstance.sum(1, 2) =', multipleInterfacesInstance.sum(1, 2));//output: 'multipleInterfacesInstance.sum(1, 2) = undefined'//console warn: 'WARNING! Function "sum(a, b)" is not overridden in MyMultipleInterfacesClass' console.log('multipleInterfacesInstance.square(2) =', multipleInterfacesInstance.square(2));//output: 'multipleInterfacesInstance.square(2) = undefined'//console warn: 'WARNING! Function "square(a)" is not overridden in MyMultipleInterfacesClass'</code> 

EDIT:

I improved the code, so now you can just use the implement (baseClass, interface1, interface2, ...) in the extension.

  / **
  * Implements any number of interfaces for this class.
  * @param cls The class you want to use
  * @param interfaces Any number of comma separated interfaces
  * @return The cls class is extended by all methods of all implemented interfaces.
  * /
  function implementation (cls, ... interfaces) {
 let clsPrototype = Object.getPrototypeOf (cls) .prototype;
 for (let me = 0; I <interfaces.length; i ++) {
  let proto = interfaces [i] .prototype;
  for (let methodName of Object.getOwnPropertyNames (proto)) {
  if (methodName! == 'constructor')
  if (typeof proto [methodName] === 'function')
  if (! clsPrototype [methodName]) {
 console.warn ('WARNING! "+ method name +' of" Interface "'+ interfaces [i]. name +'" is not declared in the class "'+ cls. name +'" ');
 clsPrototype [methodName] = proto [methodName];
  }
  }
 }
 refund cls;
  }

 // Basic interface for warning when an undefined method is used
  class MyBaseInterface {
  // declare a warning generator to see if the interface method is overridden
  // Requires a function name of the Interface method or any String that gives you a hint;)
 _WARNING (fName = 'unknown method') {
  console.warn ('WARNING! Function' '+ f name +' "is not overridden in + this.constructor.name);
 }
  }


 // create your own class
 / * This is the simplest example, but you can also use
  *
  * class MyCustomClass1 extends implementation (MyBaseInterface) {
  * foo () {return 66;}
  *}
  *
  * /
  class MyCustomClass1 extends MyBaseInterface {
 foo () {return 66;}
  }

 // create user interface
  class MyCustomInterface1 {
 // Declare your JS document in the interface to make it accessible when writing a class and for subsequent inheritance

  / **
  * Gives the sum of the given numbers
  * @param {Number} a First number
  * @param {Number} b Second number
  * @return {Number} Sum of numbers
  * /
  sum (a, b) {this._WARNING ('sum (a, b)');  }
  }

 // and other user interface
  class MyCustomInterface2 {
  / **
  * Gives the square of a given number
  * @param {Number} a The Number
  * @return {Number} Square Numbers
  * /
   () {this._WARNING (' ()');  }
  }

 // Extend your user class even further and implement user interfaces
  the AllInterfacesImplemented class extends the implementation (MyCustomClass1, MyCustomInterface1, MyCustomInterface2) {
  / **
 * @inheritdoc
 * /
  sum (a, b) {return a + b;  }

  / **
 * Multiplies two numbers
 * @param {Number} a First number
 * @param {Number} b Second number
 * @return {Number}
 * /
 multiply (a, b) {return a * b;}
  }


 // TRY THIS

  let x = new AllInterfacesImplemented ();

  console.log ("x.foo () =", x.foo ());
 // output: 'x.foo () = 66'

  console.log ("x.square (2) =", x.square (2));
 // output: 'x.square (2) = undefined
 // the console warns: "ATTENTION! The function" square (a) "is not redefined in AllInterfacesImplemented '

  console.log ("x.sum (1, 2) =", x.sum (1, 2));
 // output: 'x.sum (1, 2) = 3'

  console.log ("x.multiply (4, 5) =", x.multiply (4, 5));
 // output: 'x.multiply (4, 5) = 20'

+4
Apr 30 '19 at 7:41
source share

Given that ECMA is a language without classes, the implementation of the classical composition, in my opinion, does not make much sense. The danger is that in doing so, you are actually trying to reorganize the language (and, if someone is strongly sure of this, there are excellent holistic solutions, such as the aforementioned TypeScript, which prevents the wheel from reinventing)

However, it cannot be said that composition is out of the question in Plain Old JS. I examined this in detail some time ago. The strongest candidate I've seen to work with composition within the framework of the prototype object paradigm is stampit , which I now use in a wide range of projects. And, importantly, it adheres to a clearly defined specification.

more brand information here

+2
May 01 '19 at 3:54
source share

There are packages that can simulate interfaces.

You can use es6 interface

0
Nov 05 '18 at 7:30
source share



All Articles