为什么我更推荐你在typescript中使用type而不是interface

254 阅读2分钟

TL;DR

type与interface在大部分情况下可以实现相同的功能,但是interface的实现需要多写不少代码

interface的自动合并很可能在团队协作时出现问题

basic

type与interface是typescript中常见的用于定义类型的关键字,我们可以使用如下代码声明一个简单的type或interface

type TUserProps/* or UserProps */ = {
	name: string;
	age: string
}

interface IUserProps/* or UserProps */ {
	name: string;
	age: string;
}

我们可能会经常遇到需要对type或interface进行扩展的需求,对于type,我们可以使用&,而对于interface,我们可以使用extends关键字完成我们的需求

type UserProps = {
	name: string;
	age: string;
}

type AdminProps = UserProps & {
	role: string;
}

interface UserProps {
	name: string;
	age: string;
}

interface AdminProps extends UserProps {
	role: string;
}

到现在,type与interface看起来非常类似,这也是为什么官方文档这样写道

Type aliases and interfaces are very similar, and in many cases you can choose betweenthem freely. “

然而,相比于type,interface关键字有一些缺点需要注意

difference between type and interface

interface只能用于定义对象,而type则可以定义对象以及基础数据类型(比如string,number等),这也是为什么type也被叫做类型别名,而interface则只能被用于定义对象

type Address = string | number;
const address:Adress = 'some adress'

type可以更简洁的基于类型做诸如删除一个类型,增加一个类型的操作,而interafce虽然大部分情况下也能实现,但实现的代码较多

// for type
type UserProps = {
	name: string;
	age: string;
	createdAt: Date;
}

type GusetProps = Omit<UserProps,"name" | "age">;

// for interface
interface UserProps {
	name: string;
	age: string;
	createdAt: Date;
}

interface GuestProps extends Omit<UserProps,"name" | "age">{}

有时候,我们可能需要定义一个数组的顺序类型,在这种需求背景下,type可以很简单的满足我们的需求,而interface则需要相当复杂的实现

type Address = [number,string];

const address:Address = [1,'some address'];

interface Address extends Array<number | string> {
	0: number;
	1: string;
}

当我们需要从一个对象中提取出它的类型时,type可以非常快速的满足我们的要求

const project = {
	title: "Project 1",
	specification : {
		areaSize: 100,
		rooms: 3
	}
} as const;

type Project = typeof project; // the type definition of project!

type Specification = typeof project["specification"] // the definition of project.specification

除此之外,interface还有一个问题是它可能被自动合并

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

interface User {
	role: string
}

/**
User: {
	name: string,
	role: string,
	age: number
}
*/

当我们在一个大型项目中进行合作时,interface的自动合并很可能导致一些问题