前言
学习了第三章的类型以后,大家有没有想过定义自己的类型?
使用interface后,我们可以通过它定义自己的类型
TypeScript 不仅能帮助前端改变思维方式,还能强化面向接口编程的思维和能力,而这正是得益于 Interface 接口类型。
Interface(接口)
接口类型一般给对象,数组,函数使用
1.定义对象变量接口类型
//定义方法: interface 定义的名字,这里的括号就代表这是一个对象类型了
interface PersonInfo {
name: string;
age: number;
}
//使用我们刚刚定义的接口来定义变量的类型
let zhangsan: PersonInfo = {
// 定义的接口类型在使用时,接口里面定义了什么,,你也必须有什么不然报错
name: "张三",
age: 20,
};
注意点1:
上面的代码中我们定义了一个叫PersonInfo的接口类型,在下面我们通过zhangsan: PersonInfo也就是根上一章相同的声明方式,让这个zhangsan变成了PersonInfo类型的变量(zhangsan是一个obj对象)
注意点2:
我们定义personInfo时让他等于{xxxx},所以它首先得是一个对象,而我们在括号里声明了有name和age两个对象属性,所以当我们把personInfo给zhangsan时,zhangsan也必须有着两个属性,不然会报错,并且属性值类型也得喝接口里定义的相同
2.定义数组类型接口
interface ArrItf{
//. 声明方法: [下标类型]:值类型
[idx:number]:number|string;
}
let arr:ArrItf=[1,2,'1'];
3.定义函数类型接口
// 函数
interface funcItf{
// 声明方法 参数及类型:返回值类型
(a:number):void;
}
// ! 形参不会校验名字是不是一样的,它只看你传值类型是不是跟接口定义的一样
let fn:funcItf =(b:number)=>{
if(1){
console.log(b);
}
}
fn(1);//调用时,如果没有给接口指定的参数的话,会报错
// #endregion
注意:
很少使用接口类型来定义函数的类型,一般都是内联类型或类型别名配合箭头函数语法来定义函数类型;
接口的继承
多个不同接口之间是可以实现继承的,但是如果继承的接口和被继承的接口中有相同的属性,并且类型不兼容,那么就会报错。
// #region 接口的继承
// 可以用extends继承别的接口的属性
interface Inum{
id:number
}
interface Name{
name:string;
}
interface All extends Inum,Name{
age:number;
}
let all:All={
id:1,
name:'dad',
age:20,
}
//#endregion
思考题:多个不同的接口可以实现继承,组合成一个新的接口,那么如果出现多个相同名字的接口会怎么样?
同名
//#region 同名
// 当我们定义好了一个接口后,又用同样的名字定义了另一个,ts会帮我们把这两个你定义的值给合并起来
interface a{
a1:number
}
interface a{
a2:string;
}
let a:a={
a1:1,
a2:''
}
// #endregion
很好理解,我们可以理解成css选择器中的情况,例如我们对h1标签写两个不同的css代码块,这两个代码块中不同的样式都会给到h1,而相同但冲突的样式在ts中是会报错的,css中会根据权重进行覆盖
缺省和只读
interface ObjItf{
// 缺省:如果我们想让定义的接口中的某一项是可以有可以没有的,我们可以加上 ?
c ? :number,
// 只读 :readOnly可以让你定义的那一项不能被修改
readonly a:number,
b:string,
}
let obj:ObjItf;
obj={
a:1,
b:'1',
c:1,
// 这里没有c也不会报错,因为定义时加上了 ? 但是a,b是必须有的
}
obj.b='2'; //没问题
obj.a=2; //! 报错,因为a设置了readOnly