- Typescript Daily
- Posts
- Interfaces vs Types in Typescript. What to pick and why?
Interfaces vs Types in Typescript. What to pick and why?
Choosing the right one definitely helps!
🤔 Interface vs Types
Typescript supports both interfaces and types. Ok, what’s the problem?
They kind of solve similar problems. You can use interfaces to structure the data. You can also use types to structure the data.
Because of this similarity, there often comes a question as to what needs to be used and when.
Although this has been discussed quite a lot of times over the internet (Reddit, stack overflow, Facebook groups, Discord chats, …), I will try to summarize this article with comparisons for quick understanding.
1. Syntax
Obviously, they differ in the way we write them.
Type
Interface
2. Extending/Implementing
interface
allows you to extend otherinterfaces
using theextends
keyword:
Use interface
when you want to create a contract that other interfaces can extend to add or modify properties/methods. This is especially useful when defining interfaces for object shapes where you want to enforce a specific structure and extend it for different use cases.
type
allows you to create union or intersection types using&
and|
:
Use type
when you need to create complex type compositions, such as combining multiple types using union or intersection operators. This is particularly useful for creating flexible type definitions for functions and variables.
3. Compatibility
interface
is open to merging:
type
does not support merging:
Use type
when you want to define standalone, self-contained type aliases. This can help prevent unintentional naming conflicts.
Implications:
Merging:
interface
allows merging multiple declarations with the same name. This can be useful for gradual development and code organization. However, it may also lead to accidental merging if not used carefully.Isolation:
type
provides more isolation since it doesn't merge declarations. This can lead to better encapsulation and reduced risk of naming conflicts.
4. Declaration vs. Expression
interface
is limited to defining object shapes and methods but cannot be used as a general type alias:
Use interface
when you want to define the shape of objects, classes, or interfaces.
type
can represent a wide range of types:
Use type
when you need to create more complex and dynamic type definitions, such as aliasing primitive types, tuples, union types, or intersection types.
Implications:
Expressiveness:
type
provides greater expressiveness and flexibility for defining complex types and aliases. This can be advantageous when dealing with intricate type scenarios.
5. Immutability
interface
properties are mutable by default:
Use interface
when you want to define mutable object structures.
type
properties can be made readonly using thereadonly
modifier:
Use type
when you want to define immutable types for objects.
6. Literal Types
interface
can define index signatures with specific literal types:
Use interface
when you need to work with dynamic keys and specific literal values like "red" | "green" | "blue"
in an index signature. This is particularly useful for scenarios where you have a known set of possible values.
Use type
when you want to create literal types like string literals, numeric literals, or boolean literals:
7. Index Signatures
interface
supports index signatures to define dictionary-like objects:
Use interface
when you need to define objects with dynamic keys, such as dictionaries or associative arrays.
type
also supports index signatures:
Use type
when you require index signatures to work with dynamic key-value pairs.
8. Compatibility with Classes
interface
can be implemented by classes using theimplements
keyword:
Use interface
when you want to define a contract that classes must adhere to.
type
cannot be implemented by classes.
Use type
when you need to define complex type structures but don't require class implementation, such as function type aliases.
Implications:
Class Contracts: If you need to enforce a contract on class implementations,
interface
is the appropriate choice. However, if you need to define complex type structures unrelated to class implementations,type
is more versatile.
9. Built-in Utility Types
TypeScript provides built-in utility types that work seamlessly with both type
and interface
. These utility types are used to manipulate and transform types to make development more efficient. Some commonly used utility types include:
Partial
: Creates a new type with all properties ofT
set to optional. This is useful when you want to work with a subset of the properties of an interface.
Partial
: As withinterface
,Partial
creates a new type with all properties ofT
set to optional. This is useful when working withtype
definitions.
10. Preference for Readability
Ultimately, your choice between type
and interface
should prioritize readability and maintainability for your specific use case and coding style. There's often no strict rule, and personal/team conventions may play a role in your decision.
In summary, interface
is generally preferred for defining object shapes, class contracts, and when working with built-in utility types. On the other hand, type
is more versatile, making it suitable for creating complex types and type aliases, especially when dealing with union or intersection types. Your choice should align with the specific needs of your project and coding practices.
Reply