typescript里面 interface 和 type 的区别

标题的这个问题,最近面试遇到了四五次。

今天来解决一下

一、type和interface的定义

type关键字可以定义一个集合,可以包含各种类型的属性和值,以用来描述对象、函数、联合类型、交叉类型等。

type A = string;  // 声明了一个类型别名A,同时它的类型等价于string类型 

它的主要作用是对一组类型或一个特定类型结构进行封装,以便于在其它地方进行复用。

比如抽离一组联合类型

type StatusCode = 200 | 301 | 400 | 500 | 502;
type PossibleDataTypes = string | number | (() => unknown);

const status: StatusCode = 502;

声明一个对象类型

type Person = {
  name: string;
  age: number;
  sex: 0 | 1;
};

interface: 它定义了一个对象的形状,描述了对象应该具有的属性及类型

interface Person{
   name:string;
   age:number;
   sex:0 | 1;            
}

通过上面示例可以看出,它们两个描述对象结构时的语法略有不同。type使用等号来定义类型别名,而interface使用花括号直接定义接口的成员。

二 、type 和 interface 的可扩展性

interface: 可以通过声明合并来扩展。这意味着你可以多次声明同一个接口,并将它们合并为一个。接口支持扩展多个接口,提供了一种强大的方式来构建和契约。

interface Person{
    name:string;
}

interface Person{
    age:number
}

// 上面的两个等价于下面这个
interface Person{
    name:string;
    age:number
}

也可以使用extends 关键字进行继承

interface Fruit{
name:string
}

interface Apple extends Fruit{
 kind:stirng
}

type: 不能通过声明合并来扩展。 但是可以通过联合类型( | )和交叉类型(&)进行组合

type Name = {
    name:string
}

type Age = {
    age:number
}

type Person = Name & Age

type: 如果对类型别名进行重复定义,typescript会报错。这意味着不能重新定义一个已存在的type

type A = { x: string };
type A = { y: string }; // 错误: 重复定义

 

三、声明合并

接口:支持。

类型别名:不支持

 

四、继承与交叉类型

接口:可以通过 extends关键字继承其它接口或类。

类型别名:可以通过 & 符号创建交叉类型,以组合现有的多种类型

 

参考:

TypeScript 中的 type 和 interface:你真的了解它们的不同吗? - 掘金 (juejin.cn)

 

posted @ 2024-09-19 20:59  飞向火星  阅读(11)  评论(0编辑  收藏  举报