Interfaces
Interfaces provide a powerful way to enforce the structure of variables. As you'll recall, TypeScript relies on duck typing, which makes interfaces a key way to enforce that an object (or class) adhere to a certain schema, or contract, as defined in the interface.
Consider the following example. The function getRectangleArea
accepts anything so long as it contains length
and height
properties:
Because interfaces operate entirely at TypeScript compile time, they have zero impact at JS runtime.
The above example will simply transpile down to this JavaScript:
✨ ✨ ✨ ✨ ✨ ✨
Interfaces are extensible
Interfaces in TypeScript can be extended if necessary. Simply re-declare the interface with additional properties. The interface's properties will then be merged with any that were previously declared.
For example:
will effectively be enforced in the same way as
This can be useful, for example, if an external library defines an interface that needs to be augmented.
Optional Properties
Not all properties of an interface may be required. These optional properties are popular when creating patterns like "option bags" where you pass an object to a function that only has a couple of properties filled in.
For example:
Interfaces in classes
Interfaces can also be used to enforce classes to adhere to a certain contract.
For example:
To those unfamiliar, this might look like superfluous boilerplate. However, a lot of value is gained in the form of trust if you can make guarantees about what structure a class should have. In other words, MyDog
may be more, but for the public API it must at least be a Dog
.
Interfaces vs. type aliases
Interfaces create a new name that is used everywhere. Type aliases don’t create a new name — for instance, error messages won’t use the alias name.
A second more important difference is that type aliases cannot be extended or implemented from (nor can they extend/implement other types). Because an ideal property of software is being open to extension, you should always use an interface over a type alias if possible.
On the other hand, if you can’t express some shape with an interface and you need to use a union or tuple type, type aliases are usually the way to go.
Last updated