In TypeScript, both Types and Interfaces are used to define the types of objects. However, they have different uses and features. Both can help developers constrain the types of variables and objects when writing code, thereby reducing errors and improving code readability.
So why Types? Let's discuss this.
Types
In TypeScript, a type lets you define the shape of data. It’s flexible and can be used to create unions, intersections, and more.
type User = {
name: string;
age: number;
};
type Admin = User & {
isAdmin: boolean;
};
Interfaces
An interface is another way to define the shape of an object. It’s more rigid than types and is mainly used for defining object shapes and class contracts.
interface User {
name: string;
age: number;
}
interface Admin extends User {
isAdmin: boolean;
}
Why I Prefer Types
- Union
Union types let you define a type that can be one of several types. This is handy for function parameters and return types. Here, ID can be either a string or a number, demonstrating the power of union types.
type ID = string | number;
function getUserId(id: ID): string {
return `User ID: ${id}`;
}
- String Literals
Literal types let you specify exact values a variable can have. This can be really useful for defining constants or configuration options.
type Direction = 'north' | 'south' | 'east' | 'west';
function move(direction: Direction) {
console.log(`Moving ${direction}`);
}
move('north');
- Conditional types
Types allow the creation of conditional types, enabling the selection of types based on conditions
type Check<T> = T extends string ? string : number;
let result1: Check<string>; // result1 is of type string
let result2: Check<number>; // result2 is of type number
- Intersection
Intersection types allow you to combine multiple types into one. This is especially useful for creating complex type compositions.
type Person = {
name: string;
age: number;
};
type Employee = {
employeeId: number;
};
type EmployeeDetails = Person & Employee;
const employee: EmployeeDetails = {
name: 'Dev',
age: 30,
employeeId: 12345,
};
Choosing between types and interfaces ultimately depends on your specific use case and personal preference. However, understanding the strengths of each can help you make more informed decisions and write better TypeScript code.
Top comments (18)
I personally prefer using interfaces because of their cleaner syntax (though this is subjective). On a subconscious level, interfaces feel like contracts or shapes of data, while types seem more like value descriptions of variables. Therefore, I use interfaces for object-like structures and types for basic strings, numbers, etc. Sometimes, I also use types when I need unions or something similar.
Thanks for the post! I didn't know about conditional types 👍
Your statement concerning interfaces ("It’s more rigid than types ") is **not **correct. Interfaces have a different kind of flexibility. For instance: you can add to an interface in another location. Also, you can specify that something implements multiple interfaces. The vast majority of the time the two can be used interchangeably. When you find you need features of one over, often you can simply change from one to the other.
It is fine to have a preference, but please put no more stock into your preference for one over the other than somebody's preference of one flavor of ice cream over another. (Or even that some don't like ice cream as crazy as that seems to me.)
Interfaces support "augmentation", where you can extend an interface declared elsewhere. They are also evaluated "lazily" by
tsc
and so can be used for some recursive and circular declarations that types can complain aboutTo focus on the basic syntax is to miss the point. A simple reading of the typescript docs is time better spent than reading this article
Everything you can do with an interface, you can do using a type, but not vice versa. The approach I have seen is to use an interface whenever possible and use types otherwise. Why? I think of it like it is more "dynamic" using types
While one could use Interface to define the shape of a data, it's better to think about it as a contract.
Proper use of contract could help build loosely coupled modules.
Types help to build data type of almost any shape.
Good informations about "types". I prefer "type" also, but I saw several companies using interface for data coming from APIs.
I think one real difference is that interfaces could be inspected on runtime. It's not possible for type.
-- EDIT --
I done a few tests and it's not true. I couldn't inspect interfaces on runtime. Maybe it has no real differences, only two ways to do the same.
I prefer type too because I think it has a better syntax.
Neither type nor interface can be checked at runtime. TypeScript removes them
hi Joao, what do you mean by inspecting it on runtime?
If you have an object coming from a json, for example, you can inspect if it is compatible with some interface. But it's not possible to see if this object is compatible with a type.
Um, I had a second look on it, maybe it's not possible, not using "instanceOf" as I expected.
Then, I should think the difference is if you use classes, because classes could implements interfaces (not types), but... Just done a test and you can use "implements" for type also.
Am I the only one who saw that union example for ID and immediately felt rage? LOL
That's literally the textbook example for using TypeScript over JavaScript in the first place. Haha
I get there are good uses for it but that example just is like, why even bother then?
Taking your point, will mention good usecase examples in further blogs.
I prefer to keep it simple so that it's easy to understand the main thing which is tried to convey.
Yeah, I did get that was probably the logic, just had an immediate visceral reaction to it. But that's why I added the "lol", not truly trashing it, just chuckling over how the sight of it made me feel.
One thing I struggle to wrap my brain around is, how much of the weakness in interfaces isn't so much an issue with the Interface model/pattern as much as
an issue specifically with the Typescript implementation.
Interfaces are not just meant to be replaced with types; they have their own advantages. Use interfaces most of the time when the types of the variables are not changing much and you don’t need to extend them. If the types are likely to change, then using types is a good choice.
Everything has its purpose. Knowing when to use one over the other is what makes you a better programmer, rather than always choosing one over the other.
So there is one thing (that I know of) that can be done with an interface that can't be done with type, which is to be able to extend an existing interface in a different location. I question that practice as that seems likely to add potential confusion about what the contract is.
Other than that, so far, I've been able to do everything with types that I can accomplish with interfaces and a few things I can't. For that reason, I personally find it less taxing on my brain than having to decide when I'm going to use one over the other.
In short, my reasoning for preferring types over interfaces is that I can avoid using interfaces all the time but I can't avoid using types all the time. It keeps things nice and simple for me to always have a single answer to the question. "Should I use a type or interface here?"
Classes can implement interfaces: