TS 中 type 和 interface 的区别

9c9d09374a910b9c4e3430df5ac84e0d.png

类型别名(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)与交叉类型(intersection types)

interface 可以 extends,type 不允许 extends 和 implement 的,type 可以通过交叉类型实现 interface 的extends行为。

并且两者并不是相互独立的,也就是说 interface 可以 extends type , type 也可以与 interface 类型交叉。

两者效果差不多,但是两者语法不同。

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

type & type

type Name  = {
    name: string
}


type User = Name & {age: number}

interface extends type

type Name = {
    name: string
}


interface User extends Name {
    age: number
}

type & interface

interface Name {
    name: string
}


type User = Name & {
    age: number
}

type 可以 interface 不行

type 可以声明基本类别名,联合类型,元组类型

type Name = string
interface Dog {
  wong();
}
interface Cat {
  miao();
}


type Pet = Dog | Cat;


let a: Pet = {
  wong() {},
};

通过 typeof 获取实例的类型进行赋值

let div = document.createElement('div')
type B = typeof div

其他骚操作

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> };

interface 可以 type不行

interface 能够声明合并

interface User{
    nage: string,
    age: number,
}
interface User{
    sex: string
}


let user: User = {
    nage: '小明',
    age: 10,
    sex: '男'
}

推荐:能用 interface 就用 interface,实现不了再考虑用 type

总结

像我们提到的,类型别名可以像接口一样;然而,仍有一些细微差别。

其一,接口创建了一个新的名字,可以在其它任何地方使用。类型别名并不创建新名字—比如,错误信息就不会使用别名。在下面的示例代码里,在编译器中将鼠标悬停在 interfaced 上,显示它返回的是 Interface,但悬停在 aliased 上时,显示的却是对象字面量类型。

type Alias = { num: number }
interface Interface {
    num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;

另一个重要区别是类型别名不能被 extends和 implements(自己也不能 extends和 implements其它类型)。因为软件中的对象应该对于扩展是开放的,但是对于修改是封闭的,你应该尽量去使用接口代替类型别名。

另一方面,如果你无法通过接口来描述一个类型并且需要使用联合类型或元组类型,这时通常会使用类型别名。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值