DEV Community

Cover image for Typescript Interface vs Type
Sarah-Mohammed25
Sarah-Mohammed25

Posted on

Typescript Interface vs Type

In TypeScript, both an interface and a type Alias can be used to describe a new named type. this article will see what are the differences between them and what are the best use cases for both types and interfaces in TypeScript

1. Declaration merging

In TypeScript, declaration merging happens when the compiler merges two or more interfaces of the same name into only one declaration. and that is possible only with interfaces, if you try to declare two types of the same name, the compiler will throw an error.

Here is an example of declaration merging in TypeScript.

let's imagine we have two interfaces called Car

interface Car {
  carName: string ;
};

interface Car {
  carNumber: number;
};

const car: Car = {
  carName: "ford",
  carNumber: 12345
}
Enter fullscreen mode Exit fullscreen mode

In this example, we first declare the Car interface with one property. Then, we declare it another time, with a different property. Finally, the compiler merges both interfaces into one, since they share the same name.

if we change the interface into a type like this

type Car = { 
  carName: string ;
};

type Car = {
  carNumber: number;
};
 // this is wrong don't do it
const car: Car = {     
  carName: "ford",
  carNumber: 12345
}
Enter fullscreen mode Exit fullscreen mode

Typescript will throw us an error

Duplicate identifier Car 

'Car' is already defined.
Enter fullscreen mode Exit fullscreen mode

Declaration merging does not work with types.

2. Extends

In Typescript, we can easily extend interfaces .this is not possible with types

Interfaces can extend classes which helps a lot in a more object-oriented way of programming.

for example, there is a class called Album and an interface called Song, we can easily extend this class using an interface

class Album {

  details = () => {
    console.log("show details of the album")
  }
};

interface Song extends Album {
  songName: string;
}
Enter fullscreen mode Exit fullscreen mode

we can also extend an interface with another interface

for example, an interface called Song can extend interface Singer

interface Singer {
  artistName: string;
}

interface Song extends Singer {
  songName: string;
}
Enter fullscreen mode Exit fullscreen mode

if we tried to replace interface with type to extend, typescript will throw us an error

type Singer ={
  artistName: string;
}

type Song extends Singer ={  // this is wrong don't do it
  songName: string;
}
Enter fullscreen mode Exit fullscreen mode
Cannot find name 'extends'.
'Singer' only refers to a type, but is being used as a value here
Enter fullscreen mode Exit fullscreen mode

3. Implements

In typescript, Both a type and an interface can be implemented by a class, and we can also create classes implementing interfaces.

interface ClockInterface {
  currentTime: Date;
}

class Clock implements ClockInterface {
  currentTime: Date = new Date();
  constructor(h: number, m: number) {}
}
Enter fullscreen mode Exit fullscreen mode

You can also describe methods in an interface that are implemented in the class, as we do with setTime in the below example:

interface ClockInterface {
  currentTime: Date;
  setTime(d: Date): void;
}

class Clock implements ClockInterface {
  currentTime: Date = new Date();
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number) {}
}
Enter fullscreen mode Exit fullscreen mode

a class can also implement a type

type ClockInterface = {
  currentTime: Date;
}

class Clock implements ClockInterface {
  currentTime: Date = new Date();
  constructor(h: number, m: number) {}
}
Enter fullscreen mode Exit fullscreen mode

4. Intersection

Intersection allows the developer to merge two or more type declarations into a single type.

To create an intersection type, we have to use the & keyword

Here is an example of how to combine two types with an intersection.

type ErrorHandling = {
  success: boolean;
  error?: { message: string };
}

type ArtworksData = {
  artworks: { title: string }[];
}

type ArtworksResponse = ArtworksData & ErrorHandling;
Enter fullscreen mode Exit fullscreen mode

also, we can create a new intersection type combining two interfaces

interface ErrorHandling  {
  success: boolean;
  error?: { message: string };
}

interface ArtistsData {
  artists: { name: string }[];
}

type ArtistsResponse = ArtistsData & ErrorHandling;
Enter fullscreen mode Exit fullscreen mode

We cannot create an interface combining two types, because it doesn’t work:

type Name ={
  name: "string"
};

type Age ={
  age: number
};

interface Person = Name & Age; // this is wrong don't do it
Enter fullscreen mode Exit fullscreen mode

typescript will throw us an error

Parsing error: '{' expected.
'Name' only refers to a type, but is being used as a value here.
'Age' only refers to a type, but is being used as a value here.
Enter fullscreen mode Exit fullscreen mode

5. Tuples

  Tuples brought to us this new data type that includes two sets of values of different data types.

type specialKindOfData = [string, number]
Enter fullscreen mode Exit fullscreen mode

it is a very helpful concept in typescript, but we can only declare tuples using types and not interfaces.

but you still are able to use a tuple inside an interface.

for example.

interface Data {
  value: [string, number] 
}
Enter fullscreen mode Exit fullscreen mode

6. Unions

A union type allows the developer to create a value of one or a few more types.

we have to use the | keyword to create a new union type, the combined declaration must always be a type

type Cat = {
name: string;
};

type Dog = {
name: string;
};

type Animal = Cat | Dog;
Enter fullscreen mode Exit fullscreen mode

Similar to intersections, we can create a new union type combining two interfaces,

interface Cat {
    name: string;
}

interface Dog {
    name: string;
}

type Animal = Cat | Dog;
Enter fullscreen mode Exit fullscreen mode

we can not combine two types into an interface because union type must be combined in a type only

7. Primitive Types

A primitive type can only be declared with a type.

type data = string;
Enter fullscreen mode Exit fullscreen mode

If you try to declare one with an interface, it will not work.

Conclusion

In this article, we learned about the difference between Interfaces and types, and learned the best use cases for both types and interfaces in TypeScript, and how we can apply both of them in real projects. .to decide if you should use a type or an interface, you should carefully think and analyze what you’re working on, and the specific code to make the right choice. the interface works better with objects and method objects, and types are better to work with functions, and complex types, you can use both together and they will work fine.

Top comments (2)

Collapse
 
yw662 profile image
yw662 • Edited
type Song = { songName: string } & Singer
Enter fullscreen mode Exit fullscreen mode

is basically the same for interface ... extends.
But is a song a singer indeed ?

Collapse
 
tungtrangn profile image
Trang Tung Nguyen

Thanks for sharing!