DEV Community

Cover image for How to Choose Your Type: TypeScript Interfaces vs Types
Jagroop Singh
Jagroop Singh

Posted on

How to Choose Your Type: TypeScript Interfaces vs Types

While working with Typescript we have ever thought that if type and interface works the same then why we have 2 options? Why we need type or interface even one of them is enough for us?
But actually, even they works similar they are different from each other.
So in this blog I will clear all the doubts regarding type and interface.
So let's get's started.

In Typescript, type and interface are used to define custom types i.e. shape of object.

There syntax would be written as :

// Defining a type
type Student = {
  name: string;
  age: number;
};

// Defining an interface
interface Teacher {
  name: string;
  age: number;
}
Enter fullscreen mode Exit fullscreen mode

How they are different ?

1)Interface Support Declaration Merging.Declaration Merging means we can declare multiple interfaces with the same name, and Typescript will merge them into a single interface.

For Example:

interface Teacher {
  name: string;
}

interface Teacher {
  age: number;
}
interface Teacher {
  subject: string;
}
const teacher: Teacher = {
  name: "John",
  age: 30,
  subject:"Mathematics"
};

Enter fullscreen mode Exit fullscreen mode

On the other hand, we can't merge types in Typescript.

2)type keyword supports Computed properties but interface doesn't.

What does Computed Properties mean?

Computed properties are a way of dynamically generating property names in an object literal in TypeScript.

In TypeScript, computed properties are supported by the type keyword but not by the interface keyword. This is because interface is a declaration that describes the shape of an object, and its properties must be known at compile time. On the other hand, type is a way of defining a custom type and allows for more flexibility, including the ability to define computed properties.

Here's an example of using computed properties in a type definition:

type Student = {
  name: string;
  age: number;
  [key: string]: unknown; // Computed property
};

const student: Student = {
  name: "John",
  age: 30,
  address: "123 ABC", // Computed property
  phone: "111-111-1111", // Computed property
};
Enter fullscreen mode Exit fullscreen mode

type is very useful when we want to store key:value that is coming from API because we don't know exactly about key:vaue that is coming from API response and in future if new keys:values are added or deleted then we don't need to worry about removing it from code.

So I hope this blog will clear the doubts regarding type and interface.

If you know more interesting one please share in comments !!

Top comments (11)

Collapse
 
jackuait profile image
Евгений Пятков

There are actually more differences between interface and type keywords.

Pros of using interfaces over types:

  1. Interfaces provide better error messages. You can verify this by checking lines 48-49 of the example;
  2. Interfaces are extended with extends keyword. That comes in handy when there are conflicting fields in the objects you are trying to merge. As extending type with & keyword would not inform you about conflicting fields and also would set type never for conflicting fields. At the same time extending interface with extends keyword would inform you that provided types cannot be simultaneously extended. You can see an example of this behavior here.

So as a rule of thumb in our project we use interfaces over types when possible. Also we have a ESLint rule that helps us with this. It makes developers use interface keyword over type keyword whenever it possible.

P.S.
Also I'm not sure about the second point of the article. The given code works fine with both interface and type keywords.

Collapse
 
oadrian2 profile image
oadrian2

Interface is definitely have their place, but there's a ton of stuff you can't do with them. There's also no restriction on using one or the other. The type of a property in an interface can be a computed type that itself is not an interface.

We use them quite heavily in JSON structures that allow us to create static metadata without having to a ton of runtime checking except entry and exit points. What's inside the system we know that they correspond to our various complex type rules.

Collapse
 
works profile image
Web

Super Informative !!

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

Fantastic! I did not know about type computed properties! Thanks!!

Collapse
 
jagroop2001 profile image
Jagroop Singh

@icolomina !!
I'm delighted that my writing has benefited you!

Collapse
 
jagroop2001 profile image
Jagroop Singh

@Web
It's my pleasure that it will enhance your knowledge !!

Collapse
 
fiik346 profile image
Taufik Nurhidayat

How if I want key not needed if other key has value like

interface exampleInterface{
 title: string,
 keyOne: string, // if keyTwo has value key one is not available
 keyTwo?: string[] 
}
Enter fullscreen mode Exit fullscreen mode

How to do that?

Collapse
 
sirajulm profile image
Sirajul Muneer

Typescript is statically typed. Types are not conditional. You can look into type state pattern, but it is complex and more code in typescript. Rust has a cleaner implementation without complexity and duplication.

Another option is to make keyOne as a union.

KeyOne: TypeOne | TypeTwo | TypeTwo[]
Enter fullscreen mode Exit fullscreen mode

Last option I can think of is using generics and infer.

Collapse
 
loaderb0t profile image
Janik Schumacher

You can archive this with types pretty easily.

type exampleType = {
  title: string;
} & ({
  keyOne: string;
  keyTwo: string[];
} | never);
Enter fullscreen mode Exit fullscreen mode

Not sure if the syntax is 100% correct, I wrote this on my phone 😁

Collapse
 
kebabcase profile image
Fijasewa Arogunyo
interface Interface {
  property1: type;
  property2: type;
  [propertyName: any]: any;
}
Enter fullscreen mode Exit fullscreen mode

doesn't the last property count as a computed property?

Collapse
 
oadrian2 profile image
oadrian2 • Edited

That's not a computed property. The author is confused. The thing you can do in types that you can't do an interfaces is things like:

type Xyz = Partial<Omit<Abc, 'id'>>;
Enter fullscreen mode Exit fullscreen mode