Similar to Type Aliases, TypeScript’s Interfaces provide us a medium to avoid code duplication across our TypeScript codebases.
If we were to look at the alternative way of defining types, we would find ourselves defining and redefining types inline each time we want to benefit from TypeScript’s strong static typing system.
What Is an Interface?
Interfaces fill the role of bringing a name to the types we are used to defining and are a compelling way of expressing contracts within our code, as well as defining contracts with code outside our projects (E.g. NPM Packages).
The programming concept behind interfaces and contracts is brought under the term of Design by contract, which is a Programming Paradigm.
Interfaces may store, but are not limited to:
- Primitives
- Objects/Records
- Arrays
- Intersections
- Unions
- Type Aliases
- Generics
- Other interfaces
You can read more about the everyday types that are available to us on the TypeScript Official Docs.
Interface Syntax
The syntax for using Interfaces in TypeScript is similar to that of anonymous object type declarations.
interface MyNumberInterface {
myNumber: number;
};
interface MyStringInterface {
myString: string;
};
interface MyArrayInterface {
arr: Array<MyNumberInterface | MyStringInterface>;
}
interface MyObjectInterface {
myString: string;
myNumber: number;
};
interface Person {
firstName: string;
lastName: string;
email: string;
};
interface Address {
addressLineOne: string;
addressLineTwo?: string; // Optional Property
city: string;
stateOrProvince: string;
zipOrPostalCode: string;
country: string;
}
As you may notice, we can also define interfaces as part of other interfaces, thus making our lives much easier when dealing with nested objects or complex data structures.
As you would expect, we can also export them, thus needing to define them once in the root of our project/application and use them whenever and wherever needed.
Furthermore, we can use existing interface definitions to extend other interface definitions, thus making it easier to work with interfaces as a whole and with classes and abstract classes in TypeScript.
Extending Interfaces
Similarly to other static strongly typed languages, TypeScript provides us with the possibility to extend an interface using the following syntax:
interface Person {
firstName: string;
lastName: string;
email: string;
};
interface Address {
addressLineOne: string;
addressLineTwo?: string; // Optional Property
city: string;
stateOrProvince: string;
zipOrPostalCode: string;
country: string;
}
interface PersonWithAddress extends Person, Address {};
const person: Person = {
firstName: 'Mike',
lastName: 'Smith',
email: 'mike.smith@mail.com',
};
const address: Address = {
addressLineOne: 'Some address',
city: 'New York',
zipOrPostalCode: 'A zip code',
stateOrProvince: 'NY',
country: 'United States',
};
const personWithAddress: PersonWithAddress = {
...person,
...address,
};
We can extend as many interfaces as we wish, thus, creating a union where in our case, the PersonWithAddress
interface inherits the fields of both the Person
interface, but those of the Address
interface.
Read-only Fields
Apart from all of the features we’ve gone through above, we may also mark specific fields of an interface as being read-only, meaning that an object implementing said interface will not be able to have its read-only field reassigned:
interface ObjectWithReadonlyProperties {
readonly [property: string]: any;
};
const readonlyObject: ObjectWithReadonlyProperties = {
myProperty: 'Some value',
myOtherProperty: 'Some other value',
};
readonlyObject.myProperty = 12; // Error: "Index signature in type 'ObjectWithReadonlyProperties' only permits reading."
As outlined in the helper comment, if I were to try to reassign a read-only property I would be greeted by the following message:
Summary
Although a relatively short read, I hope you’ve enjoyed it and got a better understanding of what Interfaces are, what they are used for, the benefits they bring to the table, and how we would use them in our TypeScript applications.
Also to note, interfaces are especially useful when working with TypeScript inside React; you can check out an article highlighting the creation of a new React project with TypeScript, or even the addition of TypeScript to an already existing React project here.
Feel free to let me know whether I’ve left something important out or if you have any feedback on this article by leaving a comment using the section below.
Cheers!
Comments
[…] familiar with the concept of interfaces or what they are in TypeScript, be sure to check out this article first, as Interface Declaration Merging is linked directly to […]