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的自动合并很可能导致一些问题