一、interface:接口
interface A{
label: string;
}
const aa = ((aObj: A) => {
console.log(aObj.label);//'123'
return aObj.label;
})
aa({label: '123'})
1、可选属性
interface A{
label: string;
age?: number;
}
2、只读属性
interface A{
label: string;
age?: number;
readonly sex: string;
}
3、多余属性检查
interface A{
label: string;
age?: number;
readonly sex: string;
}
const aa = ((aObj: A) => {
console.log(aObj.label);
return aObj.label;
})
aa({label: '123', age: 12, sex: '男',name: '123'})// 报错
//避免以上报错只需加上[propName:strig]:any
interface B{
label: string;
age?: number;
readonly sex: string;
[propName:string]:any;
}
const bb = ((aObj: B) => {
console.log(aObj.label);
return aObj.label;
})
bb({label: '123', age: 12, sex: '男',name: '123'})// 正常
4、函数类型
interface A{
(a:number,b:number):void;
}
5、索引类型
interface A{
[index: number]: string
}
const arr: A = ['a', 'b', 'c']
6、类类型接口
interface A{
name: string;
age: number;
}
class B implements A{
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayHello(){
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const b = new B("Alice", 25);
7、继承多个接口
interface A{
name: string;
}
interface B{
age: number;
}
interface C extends A, B{
gender: string;
}
const c: C = {
name: "John",
age: 30,
gender: "male"
}
二、type:类型别名
type 会给一个类型起个新名字。 type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型。
type A = string
type B = () => number
type C = A | B
const c = ((value: C) =>{
if (typeof value === 'string') {
return value
}
return value()
})
1、同接口一样,类型别名也可以是泛型 - 我们可以添加类型参数并且在别名声明的右侧传入
type A<T> = { value: T };
2、也可以使用类型别名来在属性里引用自己
type A<T> = {
value: T;
a: A<T>;
}
3、与交叉类型一起使用,我们可以创建出一些十分稀奇古怪的类型。
type B<T> = T & { next: B<T> };
interface C{
name: string;
}
let c: B<C>;
let s = c.name;
let s = c.next.name;
let s = c.next.next.name;
let s = c.next.next.next.name;
4、类型别名不能出现在声明右侧的任何地方
type A= Array<A>; // 错误
三、interface和type区别
1、两者都可以用来描述对象或函数的类型,但是语法不同。
//interface
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
//type
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
2、与接口不同,类型别名还可以用于其他类型
//基本类型和联合类型可以看上面举的例子
// tuple
type Data = [number, string];
// dom
let div = document.createElement('div');
type B = typeof div;
3、两者都可以扩展,但是语法又有所不同。此外,请注意接口和类型别名不是互斥的。接口可以扩展类型别名,反之亦然。
//1、接口继承接口
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
//2、类别集成类别
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
//3、接口继承类别
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
//4、类别继承接口
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
4、接口可以定义多次,并将被视为单个接口(合并所有声明的成员)。
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
5、计算属性,生成映射类型
type 能使用 in 关键字生成映射类型,但 interface 不行。
type Keys = "firstname" | "surname"
type DudeType = {
[key in Keys]: string
}
const test: DudeType = {
firstname: "Pawel",
surname: "Grzybek"
}
// 报错
//interface DudeType2 {
// [key in keys]: string
//}
5、导出的时候也有不同
export default interface Config {
name: string
}
// export default type Config1 = {
// name: string
// }
// 会报错
type Config2 = {
name: string
}
export default Config2
三、总结
类型:对象、函数两者都适用,但是 type 可以用于基础类型、联合类型、元祖。
同名合并:interface 支持,type 不支持。
计算属性:type 支持, interface 不支持。