共同点 都可以用来描述对象(Object)和函数(Function) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 类型别名 type A_Type = { name: string, age: number } type B_Type = (args: boolean) => void const a:B_Type = (args: boolean) => args //接口类型 interface C_Interface { name: string, age: number } interface D_Interface { (args: boolean): void } const b:D_Interface = (args: boolean) => args
都可以进行继承(扩展) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 type A_Type = { name: string, } type B_Type = { age: number } interface C_Interface { sex: string, } interface D_Interface { phone: number | string } // type 继承 type type Type_Extends_Type = A_Type & B_Type & { adrress: string } const a: Type_Extends_Type = { name: '翠花', age: 18, adrress: '中国' } // interface 继承 interface interface Interface_Extends_Interface extends C_Interface, D_Interface { job: string } const b: Interface_Extends_Interface = { sex: '女', phone: 13222222222, job: '程序员' } // type 继承 interface type Type_Extends_Interface = A_Type & C_Interface const c: Type_Extends_Interface = { name: '翠花', sex: '女', } // interface 继承 type interface Interface_Extends_Type extends B_Type, D_Interface {} const d: Interface_Extends_Type = { age: 18, phone: 13222222222, }
都可以实现(implements) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // interface interface IDog { setNameFn(name: string): void } class Dog implements IDog { setNameFn(name: string): void { console.log('取名成功') } } // type type ICat = { setNameFn: (name: string) => void } class Cat implements ICat { setNameFn(name: string): void { console.log('取名成功') } }
都不会出现在编译结果里面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // ts type AA = { name: string } interface BB { age: number } const cc: AA = { name: '老王' } const dd: BB = { age: 30 } // 编译成js后 var cc = { name: '老王' }; var dd = { age: 30 };
不同点 语法不同,type需要等号,interface不需要。 interface定义的是对象的结构,而非单独的类型。
1 2 3 4 5 6 type PersonType = { name: string } interface PersonInterface { name: string }
type可以用来为任何类型(包括原始类型、函数、对象等)创建别名。 1 2 type A = string type b = number
type可以声明联合类型。 1 2 3 4 5 type C = string | number type D = { name: string } | { age: number } const e: D = { name: '老王' } const f: D = { age: 30 } const g: D = { name: '老王', age: 30 }
type可以声明元组类型。 1 2 type H = [ string, number, boolean ] const i: H = [ '老王', 30, true ]
interface 多次声明一个同名的接口可以合并 类型别名不能重复定义相同名字,会直接报错
1 2 3 4 5 6 7 8 9 10 interface Info_Interface { name: string } interface Info_Interface { age: number } const j: Info_Interface = { name: '老王', age: 30 }
扩展的方式不一样 接口使用 extends 关键字来进行扩展。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface K { name: string } interface L { age: number } interface M extends K, L { sex: string } const n: M = { name: '老王', age: 30, sex: '男' } console.log(n) // { name: '老王', age: 30, sex: '男' }
类型别名使用 & 符号进行扩展。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 type O = { name: string } type P = { age: number } type Q = { sex: string } & O & P const r: Q = { name: '老王', age: 30, sex: '男' } console.log(r) // { name: '老王', age: 30, sex: '男' }
类型别名可以使用typeof获取实例的类型进行赋值 1 2 const div = document.createElement('div') type S = typeof div // HTMLDivElement
类型别名可以使用in来实现类型映射 1 2 3 4 5 6 7 8 9 type Keys = 'name' | 'age' type T = { [ key in Keys ]: string | number } const u: T = { name: '老王', age: 30 } console.log(u) // { name: '老王', age: 30 }
总结 官方推荐用 interface,其他无法满足需求的情况下用 type。但其实,因为 联合类型 和 交叉类型 是很常用的,所以避免不了大量使用 type 的场景,一些复杂类型也需要通过组装后形成类型别名来使用。