DEV Community

Cover image for Interface vs Type in Typescript
Muhammad Ridho Anshory
Muhammad Ridho Anshory

Posted on

Interface vs Type in Typescript

My personal convention, which I describe below, is this:

Always prefer interface over type.

When to use type?

  • Use type when defining an alias for primitive types (string, boolean, number, bigint, symbol, etc)
  • Use type when defining tuple types
  • Use type when defining function types
  • Use type when defining a union
  • Use type when trying to overload functions in object types via composition
  • Use type when 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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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 interface for all object types where using type is not required (see above)
  • Use interface when 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 { ... }

Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)