In this blog post I will introduce the concept of interfaces and how they can be useful even in dynamic languages. I will also use the library Implement.js to bring the concept to JavaScript, and show you how to get some extra utility out of interfaces. What is an interface? Google defines an interface as “a point where two systems, subjects, organisations, etc. meet and interact,” and this definition holds true for interfaces in programming. In software development, an interface is a structure that enforces specific properties on an object — in most languages this object is a class. Here’s an example of an interface in Java: In the above example, the interface describes a class that has two methods with no return type, both of which take a single integer argument. The details of the implementation of each function is left up to the class, this is why the methods both have no body. To ensure a class implements the interface, we use the keyword: Car Car implements Interfaces in JavaScript Interfaces are not a thing in JavaScript, not really anyway. JavaScript is a dynamic language, one where types are changed so often that the developer may not have even realised, because of this people argue there is no need for an interface to be added to the ECMAScript standard that JavaScript is based on. However, JavaScript has grown massively as a backend language in the form of Node.js, and with that comes different requirements and a different crowd who may have a different opinion. To add to this, the language is quickly becoming front-end tool; it has got to the point where many developers will write the vast majority of their HTML inside .js files in the form of JSX. the So as the language grows to take on more roles, it is helpful then to make sure one of our most crucial data structures is what we expected it to be. JavaScript may have the keyword, but in truth this is just an uninstantiated constructor function, and once called it is simply an object. Objects are ubiquitous, so it is sometimes beneficial to ensure they match a specific shape. class Recently at work I found a case where a developer was expecting a property returned as part of an API response to be but instead got , causing a bug. An easy mistake, and one that could also have been avoided if we had an interface. true "true" But wait, there’s more! Interfaces, with a few minor modifications, could be used to reshape objects. Imagine implementing a “strict” interface, where no properties outside of the interface are permitted, we could delete or rename these properties, or even throw an error if we encounter them. So now we have an interface that will tell us when we are missing certain properties, but also when we have unexpected properties, or if the properties’ types are not what we expect. This adds other possibilities, say for example refactoring a response from an API while adding that extra layer of safety on top of the interface’s standard behaviour. We could also use interfaces in unit tests if we have them throw errors. Implement.js is a library that attempts to bring interfaces to JavaScript. The idea is simple: define an interface, define the types of it’s properties, and use it to ensure an object is what you expect it to be. Implement.js Setup First install the package: npm install implement-js Next, create a .js file and import , , and : implement Interface type Our first interface To create an interface, simply call and pass in a string as the name of your interface — it’s not recommended, but if you omit the name a unique ID will generated. This returns a function that accepts an object where the properties are all objects, a second argument can also be passed with options to show warnings, throw errors, delete or rename properties, ensure the properties of the interface are present, or to extend an existing . Interface type only Interface Here’s an interface that describes a car: It has a property that should be of type number, a passengers array that contains objects which must themselves implement the interface, and it contains a property, which should be a function. The and options have been set to true, meaning that errors will be thrown when a property of the interface is missing and also when a property on the interface is found. seats Passenger beep error strict not Implementing our interface Now we want to implement our interface, in a simple example we will create an object using an object literal and see if we are able to implement our interface. First, we create a object, then we will attempt to implement it against our interface: Ford Car As we see from the comment above, this throws an error. Let’s look back at our interface: Car We can see that while all the properties are present, strict mode is also true, meaning that the additional property causes an error to be thrown. Additionally, although we have a property, it is not an array. fuelType passengers In order to correctly implement the interface, we remove and change the value of so that it is an array containing objects that implement the interface: fuelType passengers Passenger “But JavaScript isn’t an Object-Oriented language!” It’s true that while interfaces are typically associated with object-oriented languages, and JavaScript is a multi-paradigm language that uses prototypal inheritance, interfaces can still be highly useful. For example, using we can easily refactor an API response while ensuring it has not deviated from what we expect. Here’s an example used in conjunction with : implement-js redux-thunk First, we define the interface, which extends the interface, as an object with and properties. is true meaning that we will discard any properties not described on the interface. Since our API returns properties in an unfriendly format, we have renamed the properties from and to camelcase versions of themselves. TwitterUser User twitterId twitterUsername trim TwitterUser twitter_username twitter_id Next, we define an async action with , the action triggers an API call, and we use our interface to discard properties we don’t want and to ensure it implements the properties we expect, with the correct types. If you prefer to keep your action creators pure(er) or don’t use , you may want to check the interface inside and return the result. redux-thunk TwitterUser redux-thunk twitterService.getUser Note: when extending an interface options are not inherited Unit tests are also a suitable place to use interfaces: In summary We have seen how interfaces can be useful in JavaScript: even though it is a highly dynamic language, checking the shape of an object and that it’s properties are a specific data type gives us an extra layer of safety we otherwise would be missing out on. By building on the concept of interfaces and using we have also been able to gain additional utility on top of the added security. implement-js Twitter: @josh_jahans