TypeScript中 interface 和 type 的区别

289 阅读3分钟

类型别名-type

定义: type 别名 = 类型
别名可以是任意的合法字符串,一般首字母大写

例子: type MyArr = (number | string) []

作用:给类型起别名 ---> 定义了新类型

type MyArr = (number | string) [] 
const arr1:MyArr = [1, '1'] 
const arr2:MyArr = ['a', 'b'] 

interface-接口-基本使用

作用

用interface来描述对象数据的类型(常用于给对象的属性和方法添加类型约束)

interface Person {
    name: string
    age: number
}

const p:Person = { 
    name: 'jack',
    age: 18
}

说明:一旦注解接口类型之后对象的属性和方法类型都需要满足要求,属性不能多也不能少

典型场景

场景:在常规业务开发中比较典型的就是前后端数据通信的场景

  1. 前端向后端发送数据:收集表单对象数据时的类型校验

image.png 2. 前端使用后端数据:渲染后端对象数组列表时的智能提示

image (1).png

interface接口的可选设置和继承

场景

对象的某个属性是可选的。

const goodList = [
  {id:1, name: '手机', price: 2999, imgUrl: 'http://w.g1.png'},
  {id:1, name: '毛巾', price: 9}
]

例如:从后端取回的商品数据中,一定有id,name, price,但是imgUrl是可选的。表示有些商品没有配图片。

我们这么约定goodList的格式,下面的代码会报错:

interface goodItem {
    id: number;
    name: string;
    price: number;
    imgUrl: string;
} 
const goodList: goodItem[] = [
    {id:1, name: '手机', price: 2999, imgUrl: 'http://w.g1.png'},
    {id:1, name: '毛巾', price: 9}    // 这里会报错
  ]

可选设置

概念: 通过 对属性进行可选标注,赋值的时候该属性可以缺失,如果有值必须保证类型满足要求。

格式:

interface 接口名{
	属性1:类型1,
  属性2?:类型2, // 属性2是可选的
  属性3?:类型3, // 属性3是可选的
}

代码:

interface goodItem {
    id: number;
    name: string;
    price: number;
    imgUrl?: string; // 可选的
} 
const goodList: goodItem[] = [
    {id:1, name: '手机', price: 2999, imgUrl: 'http://w.g1.png'},
    {id:1, name: '毛巾', price: 9}    // 这里也是正确的
]

接口的继承

概念:接口的很多属性是可以进行类型复用的,使用 extends 实现接口继承,实现类型复用。

// 正常的商品
interface goodItem {
    id: number;
    name: string;
    price: number;
    imgUrl?: string;
} 

// 打折的商品:正常商品 + newPrice + effectDate
interface  goodItemDiscount {
    id: number;
    name: string;
    price: number;
    imgUrl?: string;
    newPrice: number;
    effectDate: Date 
} 

继承之后

interface  goodItemDiscount extends goodItem {
    newPrice: number;
    effectDate: Date
} 

type注解对象类型

注解对象

概念:在TS中对于对象数据的类型注解,除了使用interface之外还可以使用类型别名来进行注解,作用相似

Type Person = { 
    name: string
    age: number
}

const p:Person = { 
    name: 'jack',
    age: 18
}

type + 交叉类型模拟继承

类型别名配合交叉类型(&)可以模拟继承,同样可以实现类型复用

    type GoodsType = { 
        id: string
        price: number
    }
    
    type DisGoodsType = GoodsType & { 
        disPrice: number
    }

interface 对比 type

相同点

  1. 都能描述对象类型
  2. 都能实现继承,interface使用extends, type配合交叉类型

image (2).png 不同点

  1. type除了能描述对象还可以用来自定义其他类型
  2. 同名的interface会合并(属性取并集,不能出现类型冲突)

image (3).png