【学习笔记】TypeScript中interface和type的区别

TypeScript中interface和type的区别

 

原文:https://github.com/SunshowerC/blog/issues/7

 

interface VS type

 

TypeScript中定义类型的两种方式

  1. 接口(interface)
  2. 类型别名(type alias)

interface只能定义对象类型

type声明的方式可以定义组合类型、交叉类型和原始类型

 

相同点

1. 都可以描述一个对象或者函数

interface

interface User {
    name: string;
    age: number;
}

interface SetUser {
    (name: string, age: number): void;
}

type

type User = {
    name: string;
    age: number
}

type SetUser = (name: string, age: number): void;

 

2. 都允许拓展(extends)

interface和type都可以拓展,并且两者并不是互相独立的,也就是说interface可以extends type, type也可以extends interface. 虽然效果差不多,但是语法不同。

interface extends interface

interface Name {
    name: string;
}

interface User extends Name {
    age: number;
}

type extends type

type Name = {
    name: string;
}

type User = Name & { age: number }

interface extends type

type Name = {
    name: string;
}

interface User extends Name {
    age: number;
}

type extends interface

interface Name {
    name: string;
}

type User = Name & {
    age: number;
}

 

不同点

1. type可以声明基本类型别名、联合类型、元祖等类型

// 基本类型别名
type Name = string;

// 联合类型
interface Dog {
    wong()
}
interface Cat {
    miao();
}

type Pet = Dog | Cat;

// 具体定义数组每个位置的类型
type PetList = [Dog, Pet];

 

2. type语句中还可以使用typeof获取实例的类型进行赋值

// 当你想要获取一个变量的类型时,使用typeof
let div = document.createElement('div');
type B = typeof div;

 

3. type其他骚操作

type StringOrNumber = string | number;
type Text = string | { text: string };
type NameLookup = Dictionary<string, Person>;
type Callback<T> = (data: T) => void;
type Pair<T> = [T, T];
type Coordinates = Pair<number>;
type Tree<T> = T | { left: Tree<T>, right: Tree<T> };

 

4. interface能够声明合并

interface User {
    name: string;
    age: number;
}

interface User {
    sex: string;
}

User接口为:

{
    name: string;
    age: number;
    sex: string;
}

 

总结

一般来说,能用interface实现,就用interface,如果不能就用type

 

Type Aliases的官方文档:https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases

Type aliases create a new name for a type. Type aliases are sometimes similar to interfaces, but can name primitives, unions, tuples, and any other types that you’d otherwise have to write by hand.

(类型别名为类型创建一个新名称。类型别名有时类似于接口,但可以命名原语、联合、元组和其他任何类型,否则您必须手动编写这些类型)

type Second = number;

let timeInSecond: number = 10;
let time: Second = 10;

 

Aliasing doesn’t actually create a new type - it creates a new name to refer to that type. Aliasing a primitive is not terribly useful, though it can be used as a form of documentation.

(别名实际上并不会创建一个新类型——它只是创建一个新名称来引用该类型。尽管可以将原语用作一种文档形式,但给原语起一个别名并不是非常有用)

Just like interfaces, type aliases can also be generic - we can just add type parameters and use them on the right side of the alias declaration:

(就像接口一样,类型别名也可以是泛型的-我们可以添加类型参数并在别名声明的右侧使用它们)

type Container<T> = { value: T };

We can also have a type alias refer to itself in a property:

(我们也可以有一个类型别名引用自己的属性)

type Tree<T> = {
    value: T;
    left?: Tree<T>;
    right?: Tree<T>
};

 

脑壳儿疼~~

 

posted on 2020-09-17 14:48  白小鸽  阅读(2672)  评论(0编辑  收藏  举报