Note: The term "Types" in this article is referring to the"type
" aliases in Typescript
According to the official Typescript document: "TypeScript is an open-source language that builds on JavaScript, one of the worldβs most used tools, by adding static type definitions." Implementing typescript on our project saves a lot of time in the long run. But as a developer, we should follow the best practices and standards when working with types in typescript.
In this article, we will take a look at the differences between two types type
aliases and interface
. Many developers don't really know the real difference between these two. Having known the differences, we can implement these according to the best use case for us.
Origin
Interfaces are used to define data structures, for example, an Object's shape/structure.
Types are used to define the type of data, for example: Primitive, Union, Intersection, Tuple data types.
Type Evaluation Time
There is a subtle key difference in the type evaluation period. Type evaluation on type
aliases is immediate while Type evaluation on the interface
is lazy.
Type Declaration Syntax
Even though both types and interfaces can be used in a similar way, their declaration syntax differs.
type BulldogType = {
name: string;
height: number;
weight: number;
}
interface BulldogInterface {
name: string;
height: number;
weight: number;
}
Extends & Implements keyword
In Typescript, we can extend and implement types using the interface
. This is not possible using the type
aliases.
interface Dog {
breed: string;
}
interface Bulldog extends Dog {
isCute: true;
}
Intersection
We can combine multiple types
and interface
with the"&
" keyword into a single type
. But, we cannot combine them into a single interface
.
type Bulldog = { }
type GermanShepherd = {}
type DogBreeds = Bulldog & GermanShepherd; // valid
interface IBulldog {}
interface IGermanShepherd {}
type IDogBreeds = IBulldog & IGermanShepherd; // valid
Unions
Union types allow us to create a new type that can have a value of one or a few more other types with the"|
" keyword.
We can combine multiple types
and interface
with the union keyword into a single type
. But, we cannot combine them into a single interface
.
type Bulldog = { }
type GermanShepherd = {}
type DogBreeds = Bulldog | GermanShepherd; // valid
interface IBulldog {}
interface IGermanShepherd {}
type IDogBreeds = IBulldog | IGermanShepherd; // valid
Declaration merging
interface
allows for declaration merging whilst type
aliases don't. Typescript compiler intelligently merges two or more interfaces that share the same name into only one declaration.
interface IBulldog {
name: string;
}
interface IBulldog {
weight: number;
}
const bruno: IBulldog = {
name: "Bruno",
weight: 22
}
But type
aliases can't be changed once a type is created using the type
alias. So, declaration merging isn't possible with the type
aliases.
type IBulldog = {
name: string;
}
type IBulldog = {
weight: number;
}
// Error: Duplicate identifier 'IBulldog'
Top comments (11)
An interface merge can be used to "add" new functionality to an existing class (as long as only public features are accessed):
So what is the difference between combining two types or interfaces, using '&' and using '|'.
See Naming of TypeScript's union and intersection types:
intersection of types (
&
): the shape of the data has to conform to the constraints of all the intersected types simultaneously.union of types (
|
): the shape of the data has to conform to the constraints of at least one of the unioned types.isCute: false,
but Winston IS cute :((lol just being silly. Thank you for the further clarification/doc resrouce)
thank you for explaining along with code snippets.....appreciate it!!
The & will merge the types, so all the properties of both types will be in the resulting type.
The | will give you the option to choose between all the given types, and use one of them, rather than all together :)
As a developer new to Typescript I struggle to see where I would need "type" really? π€
I am sure there are edge cases, but for now I just rely on "interface" .
Typically one is more comfortable with
interface
if one's zone of familiarity is in terms of class-oriented object orientation, i.e. one predominantly thinks of objects in terms of "instances of a class".type
is more useful when you are typing "general data". Types aren't limited to "objects as structured data" but also include literal types. Thetype
syntax also has a lot of features to pull information from JavaScript's value space into TypeScript's type space.Above
transform
andconvert
exist in JavaScript's value space whileTransform
,Key
andValue
exist in TypeScripts's type space.One of the more interesting types are discriminated unions:
So from that perspective
type
is my default - unless for some reason I'm working with classes theninterface
is a better fit.Wow appreciate your feedback. But, I think must of the stuff you described here is a bit beond my current skill level. I use typescript with React for now, and I have to admit I feel unsure why your above example wouldn't have worked equally well with "interface" instead of "types" π€
Actually it's easier to explore when to use
interface
instead oftype
:interface
declarations merge,type
aliases do not. So if it is necessary to declare an interface in bits-and-piecesinterface
is the only choice especially when monkey patching an existingclass
(which really should be avoided for built-in and even third party classes). Withtype
each piece needs to be a separate type which are then combined by intersecting them.By convention use
interface
nottype
when the declaration is going to be implemented by aclass
:While syntactically correct
a
class
should implement aninterface
, not atype
:Everywhere else use
type
to get full access to TypeScript's typing features.So for object types that are not class-based it makes sense to use
type
.Derived object types become
type
aliases, notinterface
s:type
supports Mapped Types and Generics:Most of the Utility Types are defined via
type
aliases.Because of the versatility of
type
aliases open source projects like comlink use them heavily - so being able to decipher type aliases can be helpful to understand the type constraints.By limiting yourself to
interface
you aren't leveraging TypeScript's features as much as you could.People usually get into
type
aliases once they realize how useful sum types (Union types) really are.Another nifty thing one can do with
type
:In TypeScript's type context
Email
is structurally different fromstring
- even though in JavaScript's value context it simply is astring
.This can help prevent a regular
string
from being assigned toEmail
without being validated (though a type assertion can force it) - without having to resort to a holder object:So types go beyond classes and interfaces. If you're not using
type
what are you using TypeScript for?Interface better