DEV Community

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

How to Choose Your Type: TypeScript Interfaces vs Types

Jagroop Singh on April 01, 2023

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 interf...
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
 
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
 
works profile image
Web

Super Informative !!

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
 
jagroop2001 profile image
Jagroop Singh

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

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