一、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 = stringtype B = () => numbertype C = A | Bconst 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、两者都可以用来描述对象或函数的类型,但是语法不同。
//interfaceinterface Point {x: number;y: number;
}interface SetPoint {(x: number, y: number): void;
}//typetype 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 不支持。