当前位置: 首页 > 科技观察

TypeScript中的接口和类型有什么区别?哪一个更好?

时间:2023-03-12 10:32:42 科技观察

本文转载自微信公众号《三分钟学会前端》,作者安姐。转载本文请联系三分钟学习前端公众号。接口和类型别名的异同1.都可以描述对象或函数//interfaceinterfaceSister{name:string;age:number;}interfaceSetSister{(name:string,age:number):void;}//typealiastypeSister={姓名:字符串;年龄:号码;};typeSetSister=(姓名:字符串,年龄:号码)=>void;2.接口和类型都可以扩展。也就是说接口可以扩展类型,类型也可以扩展。接口可以扩展。但需要注意的是接口的扩展是继承(extends)。类型别名的扩展是交叉类型(通过&实现)//interfaceinterfaceSisterAn{name:string;}//类型别名typeSisterRan={age:number;}//接口扩展interfaceinterfaceSisterextendsSisterAn{age:number;}//typealiasExtensiontypealiastypeSisterPro=SisterRan&{name:string;}//接口扩展类型aliasinterfaceSisterextendsSisterRan{name:string;}//类型别名扩展接口typeSisterPro=SisterAn&{age:number;}区别官方介绍的区别如下:类型别名和接口非常相似,很多情况下你可以自由选择。接口的几乎所有功能都可以在类型中使用,关键区别在于类型不能重新打开以添加新属性,而接口始终是可扩展的。这意味着接口的几乎所有特性都可以通过类型别名来实现。主要区别有:1.不同的声明作用域与接口不同,可以为任何类型创建类型别名。类型别名右侧可以是任意类型,包括基本类型、元组、类型表达式(&或|等);并且在接口声明中,右边必须是一个变量结构。例如,以下类型别名无法转换为接口typeName=stringtypeText=string|{text:string};typeCoordinates=[number,number];&toextend//接口扩展interfaceSisterAn{name:string;}interfaceSisterextendsSisterAn{age:number;}//类型别名扩展typeSisterRan={age:number;}typeSisterPro=SisterRan&{name:string;}这里需要注意的是interface扩展时,typescript会检查扩展接口是否可以赋值给扩展接口'Sister'错误地扩展了接口'SisterAn'。//属性'age'的类型不兼容。//Type'number'isnotassignabletotype'string'但是在使用交集类型时不会发生这种情况//类型别名扩展typeSisterRan={name:string;age:string;}typeSisterPro=SisterRan&{name:string;age:number;}当一个类型别名被扩展时,typescript会尽力将扩展和扩展的类型组合在一起而不会抛出编译时错误3.不同的重复定义表达式接口可以be定义多次,多次声明会自动合并string;}'butrequiredintype'Sister'constsisterRan:Sister={name:'sisterRan',age:12}//正确但是如果多次定义类型别名会报错typeSister={//Duplicateidentifier'Sister'name:string;}typeSister={//Duplicateidentifier'Sister'age:number;}如何选择接口和类型虽然官方说接口的几乎所有功能都可以通过类型别名来实现,但是还是建议先选择接口。如果接口不令人满意,则使用类型别名。typescript官网上有PreferringInterfacesOverIntersections的解释,具体内容如下:大多数时候,对象类型的简单类型别名的工作方式与interfacesinterfaceFoo{prop:string}typeBar={prop:string}非常相似;但是,一旦您需要组合两种或多种类型来实现其他类型,您就可以选择使用接口扩展这些类型,或者使用类型别名(相交类型)将它们相交于一个,这就是差异开始的地方非常重要!交集类型仅以递归方式合并属性。在某些情况下,never类型的界面可能总是显示得更好。但是,当路口类型是其他路口类型的一部分时,不能直观显示,仍然会显示。将其视为不同基本类型的组合。接口之间的类型关系被缓存,跨类型被视为一个组合的整体。最后一个值得注意的区别是在检查目标类型之前检查每个组件。因此,建议使用接口/扩展来扩展类型而不是创建交集类型。-typeFoo=Bar&Baz&{-someProp:string;-}+interfaceFooextendsBar,Baz{+someProp:string;+}简单来说,接口更符合JavaScript对象的工作方式。简单来说,当存在属性冲突时://InterfaceextensioninterfaceSister{sex:number;}interfaceSisterAnextendsSister{sex:string;}//index.ts(5,11):errorTS2430:Interface'SisterAn'incorrectlyextendsinterface'Sister'.//属性'sex'的类型不兼容。//类型'string'isnotassignabletotype'number'.//交集类型typeSister1={sex:number;}typeSister2={sex:string;}typeSisterAn=Sister1&Sister2;//不报错,此时的SisterAn是'number&string'类型,即never来源:https://github.com/Advanced-Frontend/Daily-Interview-Question