说到type
和interface
,很多时候很多人都是用的很随意,因为有时候可以用 type
,也可以用interface
。那到底什么时候 type
,什么时候用 interface
呢?
要搞明白这个问题,就显得搞明白这两者各自的特点
interface
interface
我们叫他接口,ts
设计出来主要用于定义对象类型
,可以对对象类型进行描述。比方说,我们现在要对一个对象的类型进行约束,你可以这样来
let obj: { age: number; name: string } = {age: 28, name: "constRen"}
这样写的话,树形多的时候,可能就不是很美妙了,还有就是,每写一个对象,都要去写一下类型,很麻烦。作为一个程序员,这能忍?
所以,接口就应运而生
interface User {
name: string;
age: number;
sex: string;
hobby?: string;
}
let obj1: User = {
name: '张三',
age: 28,
sex: '男',
hobby: '打篮球'
}
let obj2: User = {
name: '李四',
age: 28,
sex: '男',
}
interface addTp {
(num1: number, num2: number): number;
}
const add: addTp = (num1, num2) => {
return num1 + num2
}
这就是接口的简单用法
type
type
就是一个类型别名,说白了就是一个小名,绰号...我不相信有人每次称呼乔丹都是迈克尔乔丹,我们一般都是称之为乔丹,这就是别名,把科比布莱恩特称之为科比,把勒布朗詹姆斯称之为詹姆斯,把扬尼斯·西纳·乌戈·阿德托昆博称之为字母哥...这就是别名。他只是给类型起一个新名字(随便自定义一个类型,使用type
给他一个名字就行,加上type
的写法就是一个表达式,所以注定它用途广泛)
type Person = {
name: string
age: number
}
const my: Person = {
name: 'climblee',
age: 18
}
type addTp = (a: number, b: number) => number
const add: addTp = (a, b) => {
return a + b
}
type Name = string
const name: Name = 'climblee'
这就是type
的简单用法
两者相同点
-
都能定义函数和对象(见上面的代码)
-
都能继承(扩展)
-
interface
的继承// interface 继承 interface interface Person { name: string } interface Student extends Person { age: number } let my: Student = { name: '张三', age: 18 }
-
type
的继承// type 继承 type type Person = { name: string } type Student = Person & { age: number } let my: Student = { name: '张三', age: 18 } // type 继承 interface interface Person { name: string } type Student = Person & { age: number } let my: Student = { name: '张三', age: 18 }
-
两者不同点
type
可以,interface
不行的
type
会给一个类型起一个新名字,有时和 interface
很像,但是 type
可以作用于原始值,联合类型,元组以及其他任何你需要手写的类型
-
声明基本类型、元组
type aaa = String; const name:aaa = "wanna"
-
keyof、in、Pick、Omit、Exclude、Extract......
这些只有type
可以interface InterfaceA { key1: string; } interface InterfaceB { key2: number; } type UnionType = InterfaceA | InterfaceB; type IntersectionType = InterfaceA & InterfaceB; const obj1: UnionType = { key1: 'hello' }; // 符合 InterfaceA const obj2: UnionType = { key2: 42 }; // 符合 InterfaceB const obj: IntersectionType = { key1: 'hello', key2: 42 }; // 同时符合 InterfaceA 和 InterfaceB
-
就不一一举例了,那些
ts
的中高级以及交叉类型,基本都是使用type
interface
可以,type
不行的
-
合并重复声明:
interface
重复声明就会合并,type
不支持,会给你报个错interface A { name: string; } interface A { age: number; } // A 接口被合并为 { name: string; age: number; } const a: A = { name: 'Jack', age: 20 } // Error: Duplicate identifier 'B'. type B = { name: string; } type B = { age: number; }
-
从这个例子可以看到,本身
Person
里面只有一个name
属性,没有age
属性,但是重复声明后就会合并,就有了name
和age
两个属性,在没有加可选的情况下,少了这个属性就会报错。我们再来看type
的重复声明 -
interface
可以被类实现和扩展,而type
不行interface Animal { name: string; eat(): void; } type Animal2 { name: string; eat(): void; } class Cat implements Animal { name: string; constructor(name: string) { this.name = name; } eat() { console.log(`${this.name} is eating.`); } } // 错啦,type定义的对象类型不能被实现 class Dog implements Animal2 { name: string; constructor(name: string) { this.name = name; } eat() { console.log(`${this.name} is eating.`); } }