ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【TypeScript】对象类型定义(interface 和 type)

【TypeScript】对象类型定义(interface 和 type) 1. 声明合并interface 能合并type 不行同名 interface 会被自动合并成一个。而type是“别名”他是一次性赋值重复声明同名 type 直接报错。// interface两次声明同名编译器自动合并interfaceUser{name:string;}interfaceUser{age:number;}// 最终 User { name: string; age: number }// type重复声明直接报错typeUser{name:string};typeUser{age:number};//报错Duplicate identifier User// type 想合并得用交叉类型 这是创建新类型不是合并typeA{name:string};typeB{age:number};typeUserMergedAB;// { name: string; age: number }interface的合并是「无中生有累加到同一个名字上」特别适合给第三方库/全局对象「渐进式扩展」如给window加属性、给某个库的类型打补丁。type用是「生成第三个新类型」A 和 B 本身不变。type 注意遇到同名但类型冲突的属性会变成never。2. 继承 被类实现interface 原生支持interface可以用extends继承别的 interface也可以用implements被 class 实现。type也能被implements但「继承」得靠交叉类型来模拟没有extends关键字。代码// interface 继承interfaceAnimal{name:string;}interfaceDogextendsAnimal{// 原生 extendsbark():void;}// interface 被 class 实现classMyDogimplementsDog{name旺财;bark(){console.log(汪);}}// type 没有 extends用 模拟继承typeAnimalT{name:string};typeDogTAnimalT{bark():void};// 等价组合但语法不是继承// type 也能被 implements这点它和 interface 一样classCatimplementsDogT{name咪咪;bark(){console.log(喵);}// 字段结构对得上即可}3. type 支持任意类型interface 只支持对象/函数签名type能给任何类型起别名——基本类型、联合、元组、字面量、函数类型都能。而interface的「左边」只能描述对象结构或函数调用签名不能当基本类型别名用。代码// type什么都能别名typeIDstring|number;// 联合typePoint[number,number];// 元组typeStatussuccess|error;// 字面量联合typeCounter(x:number)void;// 函数类型// interface只能写对象/函数签名interfaceObj{x:number;y:number;}interfaceFn{// 调用签名注意没有名字(x:number):void;}// 下面这些 interface 都做不到// interface ID string | number; // 报错// interface Point [number, number]; // 报错「type是类型表达式的别名interface是结构声明」。所以number、string | number这种不是「结构」的东西只能交给type。4. 联合 / 映射 / 条件类型type 全面支持interface 不支持高级类型体操联合、映射、条件只能用type写。interface表达不了这些它只能描述「固定的对象形状」。代码// 联合类型 —— interface 无法表达typeAorB{a:1}|{b:2};// 映射类型 —— 基于已有类型批量改造interface 做不到typePartialT{[PinkeyofT]?:T[P]};// 全部变可选typeReadonlyT{readonly[PinkeyofT]:T[P]};// 条件类型 —— 根据泛型分支产出不同类型typeIsStringTTextendsstring?yes:no;typeR1IsStringstring;// yestypeR2IsStringnumber;// no// interface 想复用 mapped/conditional 的结果只能 extends 一个 typetypeBase{id:number;name:string};interfaceUserextendsBase{// interface 可以 extends typeage:number;}这也是为什么我们在 TS 源码里看到Partial、Pick、Record、ReturnType全是type写的——它们本质是「类型层面的函数计算」而 interface 只是「形状声明」两者不在同一个抽象层级。实战怎么选对外暴露的对象结构库的 API、组件 props、DTO优先interface。声明合并 继承让它能渐进扩展。需要联合 / 元组 / 映射 / 条件类型的场景只能用type。同一个对象结构用哪个都行时团队统一一个即可。区别总结声明合并interface 能合并type 不行。同名 interface 会被自动合并成一个。而type是“别名”他是一次性赋值重复声明同名 type 直接报错。继承 被类实现interface 原生支持。interface可以用extends继承别的 interface也可以用implements被 class 实现。type也能被implements但「继承」得靠交叉类型来模拟没有extends关键字。type 支持任意类型interface 只支持对象/函数签名。type能给任何类型起别名——基本类型、联合、元组、字面量、函数类型都能。而interface的「左边」只能描述对象结构或函数调用签名不能当基本类型别名用。联合 / 映射 / 条件类型type 全面支持interface 不支持。高级类型体操联合、映射、条件只能用type写。interface表达不了这些它只能描述「固定的对象形状」。
返回列表