在typescript中 interface和type都是用来自定义数据类型的重要工具,虽然在很多地方都非常的相似,但是他们之间也存在一些关键性的区别,这就使得我们在选择的时候需要权衡我们在项目之中数据类型约束的不同考量。
首先interface和type都允许我们进行自定义的数据结构定义,包括对象,函数,联合类型等。他们都提供了一种方式来增加代码的可读性和可维护性。使得typescript可以更好的捕获代码当中的一些错误的内容。
(1)看以下代码 type和interface也是有很多相似之处的,设定义的age值不为number或没有定义,type和interface都会报相应的一个错误。
//type定义的
type UserType = {
name:String,
age:number
}
//interface定义的
interface UserInter {
name:String,
age:number
}
const user: UserType = {
name:"Jack",
age:18,
}
const user2: UserInter = {
name:"Jack",
age:18,
}
name: string; // 必填项 age?: number; // 可选项
(2)interface主要作用于对象的定义 而不支持直接类型的定义
// type定义
type UserType = string;
const username:UserType = "Jack";
// interface则会直接报错
interface UserInter = string;
(3)联合数据类型 和 交叉数据类型(interface不能实现联合数据类型 可以实现交叉数据类型)
联合类型(Union Types)
联合类型表示一个值可能属于多种类型中的一种。使用 |
符号进行定义。
交叉类型(Intersection Types)
交叉类型表示将多个类型合并成一个类型。使用 &
符号进行定义。
示例:
interface Person {
name: string;
age: number;
}
interface Student {
score: number;
}
type PersonAndStudent = Person & Student;
let student: PersonAndStudent = {
name: 'Tom',
age: 18,
score: 90
};
type定义的
// 联合数据类型
type Stype = string | number;
const user:Stype = "jack";
const user2:Stype = 123;
// 交叉数据类型
type Stype2 = { name:string } & { age:number };
const user3:Stype2 = {name:"jack",age:18}
interface定义的
// 报对应的错误 不能实现联合数据类型 可以实现交叉数据类型
// interface Iuser = Iinter | Iname
interface Iinter {
age:number;
}
interface Iname {
name:string
}
//extends进行一个继承
interface Iuser extends Iinter,Iname {}
const user:Iuser = {
age:18,
name:'jack'
}
(4)重复声明
interface实行的是一个合并的操作 定义重名最终会被合并成一个user类型
interface User {
name:string;
}
interface User {
age:number
}
const user:User = {
name:"Jack",
age:18
}
type不能进行一个重复声明的操作 重复声明会报错
(5)能否实现class类的一个继承操作
interface Car {
brand:string,
speed:number
}
// ElectricCar继承了car 并且有一个自己的一个数据类型约束定义
interface ElectricCar extends Car {
batteryLife: number;
}
class Tesla implements ElectricCar {
brand: "teals";
speed: 300;
batteryLife: 360;
}
type CarType = {
brand:string,
speed:number
}
// ElectricCar继承了CarType并且有一个自己的一个数据类型约束定义
type ElectricCar = CarType & {
batteryLife: number;
}
class Tesla implements ElectricCar {
brand: "teals";
speed: 300;
batteryLife: 360;
}
事实证明 不论是type或是interface都可以进行class类的一个操作,但是我们需要注意的是,implements关键字主要用于class去实现我们接口interface的一个内容,但是,并不建议使用type来实现,因为type用于创建的是别名(不是一个接口),而不是为了类的一个实现。但是为了代码的清晰和一致性,我们通常尽力在class类implements实现的时候约束为interface的接口类型。