在 TypeScript 中,interface 和 type 都是用于定义自定义数据类型的重要工具。虽然它们在很多方面都很相似,但它们之间存在一些关键的区别,这使得在选择使用时需要权衡不同的优势。
首先interface和type都允许我们进行自定义的数据结构定义,包括对象,函数,联合类型等。他们都提供了一种方式来增加代码的可读性和可维护性。都提供了代码的可读性和可维护性,使得ts更好的推断和捕获代码当中的错误内容
(1)看以下代码 type和interface也是有很多相似之处的,设定义的age值不为number或没有定义,type和interface都会报相应的一个错误:
// object对象类型定义
type UserType = {
name: String;
age: number;
}
interface UserInter = {
name: String;
age: number;
}
const user:UserType = {
// 对UserType进行初始化操作
// 需要与UserType定义的类型一致
name: "Jack";
age: 18; // 假如我们将age去除,会出现相对于的错误
}
const UserInter = {
// 对UserInter 进行初始化操作
// 需要与UserInter 定义的类型一致
name: "Jack";
age: 18; // 假如我们将age去除,会出现相对于的错误
}
// 我们的type类型和我们interface接口类型其操作是一致的
(2)type用于语义化别名操作,提高代码可读性,在基本类型上不会额外的复杂性,因为type是用于创造复杂的数据类型或者是为现有的类型提供别名;interface主要作用于对象的定义 而不支持直接类型的定义
// type定义
type UserType = string;
const username:UserType = "Jack";
// interface则会直接报错
interface UserInter = string;
(3)联合数据类型 和 交叉数据类型(interface不能实现联合数据类型 可以实现交叉数据类型)
联合类型(Union Types)
联合类型表示一个值可能属于多种类型中的一种。使用 | 符号进行定义。
交叉类型(Intersection Types)
交叉类型表示将多个类型合并成一个类型。使用 & 符号进行定义。
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可以通过继承实现交叉数据类型的实现)
interface Iuser extends Iinter,Iname {}
const user:Iuser = {
age:18,
name:'jack'
}
(4)重复声明
interface实行的是一个合并的操作 定义重名最终会被合并成一个user类型(type是不能重复声明)
interface User {
name:string;
}
interface User {
age:number
}
const user:User = {
name:"Jack",
age:18
}
(5)能否实现class类的一个继承操作(不介意使用type,因为type用于定义别名,但是type也可以实现)
interface Car {
brand:string,
speed:number
}
// ElectricCar继承了car 并且有一个自己的一个数据类型约束定义
interface ElectricCar extends Car {
batteryLife: number;
}
// implements 关键字主要用于class实现接口interface的内容
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的接口类型。