- 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
interfaceallows you to extend otherinterfacesusing theextendskeyword:

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.
typeallows 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
interfaceis open to merging:

typedoes not support merging:

Use type when you want to define standalone, self-contained type aliases. This can help prevent unintentional naming conflicts.
Implications:
Merging:
interfaceallows 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:
typeprovides more isolation since it doesn't merge declarations. This can lead to better encapsulation and reduced risk of naming conflicts.
4. Declaration vs. Expression
interfaceis 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.
typecan 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:
typeprovides greater expressiveness and flexibility for defining complex types and aliases. This can be advantageous when dealing with intricate type scenarios.
5. Immutability
interfaceproperties are mutable by default:

Use interface when you want to define mutable object structures.
typeproperties can be made readonly using thereadonlymodifier:

Use type when you want to define immutable types for objects.
6. Literal Types
interfacecan 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
interfacesupports index signatures to define dictionary-like objects:

Use interface when you need to define objects with dynamic keys, such as dictionaries or associative arrays.
typealso supports index signatures:

Use type when you require index signatures to work with dynamic key-value pairs.
8. Compatibility with Classes
interfacecan be implemented by classes using theimplementskeyword:

Use interface when you want to define a contract that classes must adhere to.
typecannot 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,
interfaceis the appropriate choice. However, if you need to define complex type structures unrelated to class implementations,typeis 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 ofTset to optional. This is useful when you want to work with a subset of the properties of an interface.

Partial: As withinterface,Partialcreates a new type with all properties ofTset to optional. This is useful when working withtypedefinitions.

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