26 Dec
26Dec

When we use Typescript then we start using interfaces and types without understanding the difference between them as both concepts share similarities. But there are some differences which I am highlighting so that we can make a right choice. 


Type and type aliases:

TypeScript has primitive types such as boolean, number, string, etc. And if we want to declare advanced types, we use what are called type aliases. 

Type aliases refer to the process of creating a new name for a type. It is important to note that we are not defining a new type. The “type” keyword we use to do so might lead us to believe that we are creating a new type, but we are only giving a type a new name. 

So whenever someone refers to types, the reference is aimed at type aliases.


Interfaces:

Interfaces, on the contrary to types, are restricted to object types. They are a way to describe an object and its properties. Type alias declarations can be used for any primitive type, unions, or intersections. In that regard, interfaces are restricted to object types.


1. Objects / Functions

Both can be used to describe the shape of an object or a function signature. But the syntax differs.

Interface interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}
Type aliastype Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;



2. Other Types

Unlike an interface, the type alias can also be used for other types such as primitives, unions, and tuples.

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];


3. Extend

Both can be extended, but again, the syntax differs. Additionally, note that an interface and type alias are not mutually exclusive. An interface can extend a type alias, and vice versa.

Interface extends interfaceinterface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Type alias extends type aliastype PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
Interface extends type aliastype PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Type alias extends interfaceinterface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };


4. Implements

A class can implement an interface or type alias, both in the same exact way. Note however that a class and interface are considered static blueprints. Therefore, they can not implement / extend a type alias that names a union type.

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}



5. Union and intersection types

Though interfaces can be extended and merged (next point), they cannot be composed together in the form of unions and intersections. Types can make use of union and intersection operators to form new types.

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// intersection
type PartialPoint = PartialPointX & PartialPointY;


6. Declaration merging

Unlike a type alias, an interface can be defined multiple times, and will be treated as a single interface (with members of all declarations being merged). If we try and create two types with the same name but different properties, the TypeScript compiler will throw an error.

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };


7. Tuple types

Tuples (key-value pairs) can only be typed via the type keyword.

type Point = [x: number, y: number];

There is no way to declare a tuple using an interface.We can use a tuple inside an interface though:

interface Point { coordinates: [number, number] }


Which one should I use?

In general, both interface and type are pretty similar as noted before.

For public API definitions in a library or third-party type definition, an interface should be used to provide declaration merging capabilities.

Apart from that, we can use whichever we want, but there should be consistency across the codebase.


Rule of Thumb for React case:

always use interface for public API's definition when authoring a library or 3rd party ambient type definitions, as this allows a consumer to extend them via declaration merging if some definitions are missing.

consider using type for your React Component Props and State, for consistency and because it is more constrained.


Comments
* The email will not be published on the website.