Interfaces in TypeScript.

Interfaces in TypeScript allow declaring which attributes an object should have and of what type, as well as the methods that an object should implement, but it does not define how these should be implemented.
Attributes
To declare attributes we can use the following syntax. Notice how we have defined an interface that requires two attributes, name and age, as well as their type.
interface User {
name: string,
age: number
}
Optional attributes
It is possible to declare that certain attributes or functions can be defined optionally. For this, unlike other programming languages, the ?
character is used in the name and not the type.
interface User {
name: string,
age?: number,
addNote?: (note: string) => void
}
Read-only attributes
It is possible to define attributes that are only for reading. With this, it would be impossible to try to reassign an attribute once initialized.
interface User {
readonly type: string;
}
Attributes within a stack
If we want to define a set of possible values for an attribute, we can use the pipe character.
interface User {
type: 'Admin' | 'Guest';
name: string;
}
It is also possible to define an attribute with an enum type.
enum UserType {
Admin,
Guest
}
interface User {
type: UserType;
name: string;
}
To see more about the enum type you can go to our post on Enums in TypeScript.
Methods
To declare methods we can use two different syntaxes. Let's see below how we define the addNote method.
Way 1
interface User {
addNote(note: string): void;
}
Way 2
interface User {
addNote: (note: string) => void;
}
Extension
To extend a type, we can do it using the reserved keyword extends
.
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
In the previous example, first the type alias Animal
is defined. Later it is extended by creating the alias of type Bear
. The latter type requires both attributes mandatorily.
Another interesting variation of this feature, very common in most programming languages, is that an interface can extend more than one interface without even defining new attributes. In this case, it is like merging the two interfaces into one. Let's see the following example.
interface Contact {
name: string;
birthDate: Date;
}
interface Address {
line1: string;
line2?: string;
}
interface User extends Contact, Address {};
Any class that implements the User
interface must now have the name, birthDate and line1 attributes mandatorily and optionally line2.
Type modification
Unlike Type Aliases in TypeScript, an interface can be modified to add more attributes than it originally had.
interface Window {
title: string
}
interface Window {
ts: TypeScriptAPI
}
In the previous example, the Window
type ends up having two mandatory attributes, title and ts.