If you’ve ever worked with TypeScript, you’ve worked with Interface and Type.

Think about it for five seconds. What are the similarities and differences between them?

If you have no idea how different they are, read on.

If we declare a Point type, we can achieve the desired result in one of two ways:

interface Point {
  x: number;
  y: number;
}
Copy the code

or

type Point = {
  x: number;
  y: number;
}
Copy the code

The above example does not show the difference between interface and type.

Let’s explore further.

TypeScript types include primitive data types, object types, advanced types, and so on.

Primitive data types include: Boolean, Number, String, NULL, undefined, and the new types Symbol in ES6 and BigInt in ES10.

Advanced Types: Unions Type, Generics

Unions Type

Union Types indicate that the value can be one of many Types.

Here’s an example:

function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// Error
printId({ myID: 22342 });
// Throw an error message
//Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
// Type '{ myID: number; }' is not assignable to type 'number'.
Copy the code

{myID: number;}} {myID: number; }’ assigns either string or number.

function printId(id: number | string) {
  console.log(id.toUpperCase());
}

//Error
Property 'toUpperCase' does not exist on type 'string | number'.
  Property 'toUpperCase' does not exist on type 'number'.
Copy the code

The toUpperCase attribute is only available for strings of type string. The number type does not have the toUpperCase attribute, which causes an error when inferring ts. Feels like TypeScript is smart enough to sense errors ahead of time.

If you want to support both string and number parameters, you need to improve. As follows:

function printId(id: number | string) {
  if (typeof id === "string") {
    // In this branch, id is of type 'string'
    console.log(id.toUpperCase());
  } else {
    // Here, id is of type 'number'
    console.log(id); }}Copy the code

Type Aliases

A type alias is a new name for a type. Note that instead of defining a new type, a new name is given.

Type aliases are often used for primitive types, Unions Type.

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

// Exactly the same as the earlier example
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}

printCoord({ x: 100.y: 100 });
Copy the code

The joint type

type ID = number | string;
Copy the code
type UserInputSanitizedString = string;

function sanitizeInput(str: string) :UserInputSanitizedString {
  return "inputcontent"
}
Copy the code

A type alias is a new name for a type, so the following string and UserInputSanitizedString are of the same type

Object type – interface

In TypeScript, we use Interfaces to define object types. In contrast to type aliases, Interfaces are used only for object types.

Inherit – the extend

Interface and type support inheritance, and interface can inherit type, and type can inherit interface, but the syntax is different. For example:

1.interface extend interface

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Copy the code

2.interface extend type

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Copy the code
  1. type & type
type PartialPointX = { x: number; };
// The inheritance is used with &
type Point = PartialPointX & { y: number; };
Copy the code
  1. type & interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Copy the code

Implementation – Implements

A class can implement interface and Type, but not implement a union type.

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

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

type AnotherPoint = {
  x: number;
  y: number;
};
class SomePoint2 implements AnotherPoint {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };
// cannot implement a union type, the following code will throw an exception
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}
Copy the code

Declaration Merging – Declaration Merging

TypeScript compiles interfaces with the same name, but not types.

Look at a simple example where the interface name is the same, but the attribute name is different

interface Box {
  height: number;
  width: number;
}
interface Box {
  scale: number;
}
let box: Box = { height: 5.width: 6.scale: 10 };
Copy the code

The above example combines the two Box types into the following result

interface Box {
  height: number;
  width: number;
  scale: number;
}
let box: Box = { height: 5.width: 6.scale: 10 };
Copy the code

Let’s do another example where the interface name is the same, but the property name is the same

interface Cloner {
  clone(animal: Animal): Animal;
}
interface Cloner {
  clone(animal: Sheep): Sheep;
}
interface Cloner {
  clone(animal: Dog): Dog;
  clone(animal: Cat): Cat;
}
Copy the code

The result of merging the three Cloner interfaces is as follows:

interface Cloner {
  clone(animal: Dog): Dog;
  clone(animal: Cat): Cat;
  
  clone(animal: Sheep): Sheep;
  
  clone(animal: Animal): Animal;
}
Copy the code

On closer inspection, after the merge, the attributes of the third interface are ranked first and have the highest priority. You have to pay attention to that

InterfaceandTypeHow to choose?

Above, we compared the similarities and differences between Interface and Type. So let me summarize.

Define public apis for in-library or third-party library types, using interfaces to provide declarative merge capabilities.

Other than that, let’s do whatever we want, but keep the code consistent.

The resources

www.typescriptlang.org/docs/handbo…

Javascript. Plainenglish. IO/typescript -…