本文转载自微信公众号「三分钟学前端」,作者sisterAn。转载本文请联系三分钟学前端公众号。
创新互联是专业的弋阳网站建设公司,弋阳接单;提供成都网站设计、网站制作、外贸营销网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行弋阳网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
1. 都可以描述对象或函数
- // 接口
- interface Sister {
- name: string;
- age: number;
- }
- interface SetSister {
- (name: string, age: number): void;
- }
- // 类型别名
- type Sister = {
- name: string;
- age: number;
- };
- type SetSister = (name: string, age: number) => void;
interface 和 type 可以混合扩展,也就是说 interface 可以扩展 type,type 也可以扩展 interface。
但需要注意的是,接口的扩展是继承( extends )。类型别名的扩展就是交叉类型(通过 & 实现)
- // 接口
- interface SisterAn {
- name: string;
- }
- // 类型别名
- type SisterRan = {
- age: number;
- }
- // 接口扩展接口
- interface Sister extends SisterAn {
- age: number;
- }
- // 类型别名扩展类型别名
- type SisterPro = SisterRan & {
- name: string;
- }
- // 接口扩展类型别名
- interface Sister extends SisterRan {
- name: string;
- }
- // 类型别名扩展接口
- type SisterPro = SisterAn & {
- age: number;
- }
官方 中这样介绍两者的区别:
Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
意思就是说几乎接口的所有特性都可以通过类型别名来实现,主要区别在于:
1. 不同的声明范围
与接口不同,可以为任意的类型创建类型别名
类型别名的右边可以是任何类型,包括基本类型、元祖、类型表达式( & 或 | 等);而在接口声明中,右边必须为变量结构。例如,下面的类型别名就不能转换成接口
- type Name = string
- type Text = string | { text: string };
- type Coordinates = [number, number];
2. 不同的扩展形式
接口是通过继承的方式来扩展,类型别名是通过 & 来扩展
- // 接口扩展
- interface SisterAn {
- name: string;
- }
- interface Sister extends SisterAn {
- age: number;
- }
- // 类型别名扩展
- type SisterRan = {
- age: number;
- }
- type SisterPro = SisterRan & {
- name: string;
- }
这里需要注意的是,接口扩展时,typescript 会检查扩展的接口是否可以赋值给被扩展的接口
- // 接口扩展
- interface SisterAn {
- name: string;
- age: string
- }
- interface Sister extends SisterAn {
- name: string;
- age: number;
- }
- // 报错:
- // Interface 'Sister' incorrectly extends interface 'SisterAn'.
- // Types of property 'age' are incompatible.
- // Type 'number' is not assignable to type 'string'
但使用交集类型时就不会出现这种情况
- // 类型别名扩展
- type SisterRan = {
- name: string;
- age: string;
- }
- type SisterPro = SisterRan & {
- name: string;
- age: number;
- }
类型别名扩展时,typescript 将尽其所能把扩展和被扩展的类型组合在一起,而不会抛出编译时错误
接口可以定义多次,多次的声明会自动合并
- interface Sister {
- name: string;
- }
- interface Sister {
- age: number;
- }
- const sisterAn: Sister = {
- name: 'sisterAn'
- }
- // 报错:Property 'age' is missing in type '{ name: string; }' but required in type 'Sister'
- const sisterRan: Sister = {
- name: 'sisterRan',
- age: 12
- }
- // 正确
但是类型别名如果定义多次,会报错
- type Sister = { // Duplicate identifier 'Sister'
- name: string;
- }
- type Sister = { // Duplicate identifier 'Sister'
- age: number;
- }
虽然 官方 中说几乎接口的所有特性都可以通过类型别名来实现,但建议优先选择接口,接口满足不了再使用类型别名,在 typescript 官网 Preferring Interfaces Over Intersections 有说明,具体内容如下:
大多数时候,对象类型的简单类型别名的作用与接口非常相似
- interface Foo { prop: string }
- type Bar = { prop: string };
但是,一旦你需要组合两个或多个类型来实现其他类型时,你就可以选择使用接口扩展这些类型,或者使用类型别名将它们交叉在一个中(交叉类型),这就是差异开始的时候。
接口创建一个单一的平面对象类型来检测属性冲突,这通常很重要! 而交叉类型只是递归的进行属性合并,在某种情况下可能产生 never 类型
接口也始终显示得更好,而交叉类型做为其他交叉类型的一部分时,直观上表现不出来,还是会认为是不同基本类型的组合。
接口之间的类型关系会被缓存,而交叉类型会被看成组合起来的一个整体。
最后一个值得注意的区别是,在检查到目标类型之前会先检查每一个组分。
出于这个原因,建议使用接口/扩展扩展类型而不是创建交叉类型。
- - type Foo = Bar & Baz & {
- - someProp: string;
- - }
- + interface Foo extends Bar, Baz {
- + someProp: string;
- + }
简单的说,接口更加符合 JavaScript 对象的工作方式,简单的说明下,当出现属性冲突时:
- // 接口扩展
- interface Sister {
- sex: number;
- }
- interface SisterAn extends Sister {
- sex: string;
- }
- // index.ts(5,11): error TS2430: Interface 'SisterAn' incorrectly extends interface 'Sister'.
- // Types of property 'sex' are incompatible.
- // Type 'string' is not assignable to type 'number'.
- // 交叉类型
- type Sister1 = {
- sex: number;
- }
- type Sister2 = {
- sex: string;
- }
- type SisterAn = Sister1 & Sister2;
- // 不报错,此时的 SisterAn 是一个'number & string'类型,也就是 never
来源:https://github.com/Advanced-Frontend/Daily-Interview-Question
网站标题:TypeScript中Interface与Type的区别?该用哪个比较好?
URL地址:http://www.mswzjz.com/qtweb/news36/191286.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联