Understanding Types in TypeScript: "Interface" vs. "Type" vs. "Class"
interfacevstypevsclass
12 snippets
32 mins
Fabio Biondi
Google Developer Expert Microsoft MVP
In TypeScript, a type is a way to define the shape of an object, specifying what properties it should have and what types those properties should be. Types provide a way to ensure that values match expected structures, helping catch errors during development.
Defining types is essential for ensuring type safety and enhancing code readability and in TypeScript they can be created using type, interface and class.
While interfaces, types, and classes all serve similar purposes, they have distinct features and use cases.
Interfaces are a fundamental concept in TypeScript, used to define the shape of objects. They declare a contract that other objects must adhere to, specifying the properties and methods they should have.
Here's an example of an interface in TypeScript to defines an interface named User with two properties:
name as a string and age as number:
Now you can assign this type to a property.
If you forget to assign a property or get its content wrong (for example you assign a number to a string) you will receive an error from TypeScript:
You can also define an array of User. You'll get an error if one of the students don't include all properties or if you assigned values of the wrong type:
Try it with the Code Playground:
SWITCH LAYOUT
Correct Example
The User interface defines a blueprint for objects with name and age properties. Implementing objects must provide these properties:
With error
Here we're not providing all the necessary properties to the student object so TypeScript will throw an error:
Play the example above, move the mouse over student property and read the TypeScript message that contains the error (see screenshot below):
Real World projects
In a real world project, for example when you create an Angular or a React/TypeScript project, an error in TypeScript will generate a compile error and the application will no longer work.
This behavior is completely different from a "classic" JavaScript application where it will continue to work and you'll probably receive a runtime error.
Basically it is the user who will encounter the error during usage while with a typescript error we will be blocked before going to production
To create Users with or without the age properties, we can set it as optional by using the question mark (?).
In fact, the script below now create an User type with an optional age property
"Optional" properties are particularly useful in situations where you might not have all the data upfront or certain fields are not always applicable. They provide flexibility in your type definitions, making your code more adaptable to different scenarios.
TypeScript utilities types
There are other cool ways to handle scenarios like this by using the TypeScript utilities types :
Partial, Pick, Omit and others. We'll talk about it in another recipe
type in TypeScript seems very similar to interface but they are very useful to provide aliases for other types, allowing you to create reusable type annotations.
Here you can see a snippet with type that does exactly the same thing as the previous interface example:
In most cases you can use interface and type interchangeably but each of them offers different features that may be useful in the future and that we'll talk about in the next recipes
Here an example that can only be done using type.
Age represents a new type that hold a number and we use it in the User type to define the type of the age property.
This cannot be done with interface.
Here a working example where the variable myAge can contains a string or a number and both won't generate errors:
The vertical bar (|) is used to separate the different types that Age can be.
The union type is more complex than it seems but currently it is only important if you realize the potential of the type with respect to the interface.
We'll deeply describe it in the lessons about Union types
Classes are used for creating objects based on blueprints with both properties and methods.
They encapsulate data and behavior, facilitating object-oriented programming principles like encapsulation and inheritance:
The User class has three properties: name (required), age (optional) and role that is not required and has a default value.
The constructor initializes these properties. If age is provided, it sets the age property; otherwise, it leaves it as undefined.
If role is not passed as parameter, the default value is assigned ('moderator')