In the process of writing TS related code, you can always see interface and type. Their functions seem to be the same, the same function can be realized with either one, and they are also very easy to use, so I rarely really understand what the difference is between them, respectively in what scenarios to use, to share their learning content record

Type alias type

First, what is a type alias?

Type aliases are used to give a type a new name. Type aliases are created using type. Type aliases can be used to represent not only basic types, but also object types, union types, tuples, and intersections. Let’s look at some examples:

type userName = string; / / basic type type userId = string | number; // join type arr = number[]; Type Person = {id: userId; // You can define the type name: userName; age: number; gender: string; isWebDev: boolean; }; // Type Tree<T> = {value: T}; Const user: Person = {id: "901", name: "toon ", age: 22, gender:" female ", isWebDev: false,}; const numbers: arr = [1, 8, 9];Copy the code

Interface interface

Interfaces are another way to name data structures, such as objects; Unlike type, interface is limited to describing object types.

The declaration syntax of an interface is also different from the declaration syntax of a type alias. Let’s rewrite the above type alias Person as an interface declaration:

interface Person {
    id: userId;
    name: userName;
    age: number;
    gender: string;
    isWebDev: boolean;
}
Copy the code

Similarities between interface and type

Before we discuss the differences, let’s first look at the similarities (why we think it’s the same in development).

Can be describedObjectandFunction

Both can be used to describe objects or functions, but the syntax is different:

Type

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

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

Interface

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

interface SetPoint {
  (x: number, y: number): void;
}
Copy the code

Both can be inherited

Both interface and type can be inherited.

It is also worth noting that interface and type aliases are not mutually exclusive. Type aliases can inherit interfaces and vice versa. It’s just a slightly different form of implementation.

Interface inheritance interface

interface Person{
    name:string
}

interface Student extends Person { stuNo: number }
Copy the code

Interface inheritance type

type Person{
    name:string
}

interface Student extends Person { stuNo: number }
Copy the code

Type inheritance type

type Person{
    name:string
}

type Student = Person & { stuNo: number }
Copy the code

Type interface inheritance

interface Person{
    name:string
}

type Student = Person & { stuNo: number }
Copy the code

Implementation implements

Classes can implement interfaces and types (in addition to union types)

interface ICat{
    setName(name:string): void;
}

class Cat implements ICat{
    setName(name:string):void{
        // todo
    }
}

// type 
type ICat = {
    setName(name:string): void;
}

class Cat implements ICat{
    setName(name:string):void{
        // todo
    }
}
Copy the code

What do I mean by the special case mentioned above that a class cannot implement a union type?

type Person = { name: string; } | { setName(name:string): void }; // The union type Person cannot be implemented // error: A class can only implement an object type or intersection of object types with statically known members. class Student Implements Person {name= "Person "; setName(name:string):void{ // todo } }Copy the code

Interface and Type are similar.

The difference between

1. Define basic type aliases

Type can define a basic type alias, but interface cannot, for example:

type userName = string
type stuNo = number
...
Copy the code

2. Specify the association type

Type can declare the union type, for example:

type Student = {stuNo: number} | {classId: number}
Copy the code

3. Declare a tuple

Type can declare a tuple type:

type Data = [number, string];
Copy the code

These are all things that type can do, but interface can’t. Let’s talk about what Type can’t do

4. Declare the merger

If you declare an interface with the same name multiple times, TypeScript merges them into a single declaration and treats them as one interface. This is called declarative merging, for example:

interface Person { name: string }
interface Person { age: number }

let user: Person = {
    name: "Tolu",
    age: 0,
};
Copy the code

In this case, repeating Person as type will cause an error:

type Person { name: string }; // Error: identifier "Person" is repeated. ts(2300) type Person { age: number }Copy the code

5. Index signature problem

If you use TypeScript a lot, you’ve probably encountered a similar error:

Type ‘xxx’ is not assignable to type ‘yyy’

Index signature is missing in type ‘xxx’.

Look at an example to understand the question:

interface propType{ [key: string] : string } let props: propType type dataType = { title: String} interface dataType1 {title: string} const data: dataType = {title: "order page "} const data1: dataType1 = {title: } props = data // Error: type "dataType1" cannot be assigned to type "propType"; Missing index signature of type "dataType1" props = data1Copy the code

DataType = dataType1; interface = dataType1; interface = dataType1; Puzzled at first, I finally found a similar question on Stack Overflow:

And I was lucky to find an answer that worked:

The translation roughly translates to:

Record

same as {[key:string] :string}. Subsets are allowed to be assigned to an index signature type only if all attributes of the type are known and can be checked against the index signature. In your example, everything from exampleType to Record

is allocatable. This checks only for object literal types, because once they have been declared, they cannot be changed. Therefore, the index signature is known.
,string>
,string>

In contrast, when you declare variables using an interface, their type is not the final type at the moment. Because Interfac can do declarative merging, it is always possible to add a new member to a type defined by the same interface.

Combine this with the explanation of declaration merging at 👆 4, and it makes sense. The type defined by interface is undefined.

interface propType{
    title:number
}
Copy the code

So the propType type is changed.

conclusion

Interface is officially recommended, and type is used when other requirements cannot be met.

However, because associative and crossover types are common, you can’t avoid a lot of type usage scenarios, and some complex types need to be used through type aliases after assembly.

So, if you want to keep the code uniform, you can still use Type. Based on the above comparison, type aliases actually cover most scenarios of an interface.

For the React component, use type for props and state. This ensures that properties cannot be added to components where they are used. If there is a need for customization, HOC secondary encapsulation can be used.

Interface is used when writing tripartite libraries, whose more flexible automatic type merging allows for complex usage scenarios that are unknown.

References:

  • TypeScript: Type alias and interface

Reprinted from: mp.weixin.qq.com/s/Fn7c5a63P…