My personal convention, which I describe below, is this:
Always prefer interface over type.
When to use type?
- Use
typewhen defining an alias for primitive types (string, boolean, number, bigint, symbol, etc) - Use
typewhen defining tuple types - Use
typewhen defining function types - Use
typewhen defining a union - Use
typewhen trying to overload functions in object types via composition - Use
typewhen needing to take advantage of mapped types
Additions:
Generic Transformations
Use the type when you are transforming multiple types into a single generic type.
Example:
type Nullable<T> = T | null | undefined
type NonNull<T> = T extends (null | undefined) ? never : T
Type Aliasing
We can use the type for creating the aliases for long or complicated types that are hard to read as well as inconvenient to type again and again.
Example:
type Primitive = number | string | boolean | null | undefined
Creating an alias like this makes the code more concise and readable.
Type Capturing
Use the type to capture the type of an object when the type is unknown.
Example:
const orange = { color: "Orange", vitamin: "C"}
type Fruit = typeof orange
let apple: Fruit
Here, we get the unknown type of orange, call it a Fruit and then use the Fruit to create a new type-safe object apple.
When to use interface?
- Use
interfacefor all object types where usingtypeis not required (see above) - Use
interfacewhen you want to take advantage of declaration merging.
Additions:
Polymorphism
An interface is a contract to implement a shape of the data. Use the interface to make it clear that it is intended to be implemented and used as a contract about how the object will be used.
Example:
interface Bird {
size: number
fly(): void
sleep(): void
}
class Hummingbird implements Bird { ... }
class Bellbird implements Bird { ... }
Though you can use the type to achieve this, the Typescript is seen more as an object oriented language and the interface has a special place in object oriented languages. It's easier to read the code with interface when you are working in a team environment or contributing to the open source community. It's easy on the new programmers coming from the other object oriented languages too.
The official Typescript documentation also says:
... we recommend using an interface over a type alias when possible.
This also suggests that the type is more intended for creating type aliases than creating the types themselves.
Declaration Merging
You can use the declaration merging feature of the interface for adding new properties and methods to an already declared interface. This is useful for the ambient type declarations of third party libraries. When some declarations are missing for a third party library, you can declare the interface again with the same name and add new properties and methods.
Example:
We can extend the above Bird interface to include new declarations.
interface Bird {
color: string
eat(): void
}
That's it! It's easier to remember when to use what than getting lost in subtle differences between the two.
PS: According to TypeScript handbook the answer is:
Almost all features of an interface are available in type.The key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
Top comments (0)