接口作用
描述一个对象的取值规范;
通俗的说:规定一个对象有哪些属性,属性的类型是什么
注:下文接口统一取名:my_interface;简写: MIF
定义 与使用 interface
// 定义一个名为MIF的接口,
// 这个接口有一个属性为id,id的类型是number
interface MIF {
id:number
}
使用方法一:
let info = <MIF>{};
info.id = 88; // 正确
info.ii = 88; // 错误
使用方法二:
let info1 : MIF = { id: 88 }; // 正确
let info2 : MIF = { ii:88 }; // 错误:参数名错误
let info2 : MIF = { id:88, title:'ss' }; // 错误:带有未定义参数
可选属性属性名后加?
// 带?的属性名,赋值时是可选的,不是必备的
interface MIF {
id:number,
name?:string
}
let info1 : MIF = {id:88}; // 正确:未带可选参数
let info2 : MIF = {id:88, name:'ss'}; // 正确:带有可选参数
let info3 : MIF = {id:88, name:'ss', detail:'dd'}; // 错误:带有未定义参数
只读属性属性名前加readonly
interface MIF {
readonly id:number
}
let info1 : MIF = {id:3}; // 创建并赋值
info1.id = 8; // 错误:因为id是只读属性,定以后无法修改
注意:
readonly
用于对象的属性
const
用于变量常量
未明确命名的属性 [prop_name:string] : any
interface MIF {
id:number
}
let info :MIF = {id:1, name:'dd',age:32}; // 错误:因为name和age未定义
interface MIF {
id:number,
[prop_name:string]:any
}
let info :MIF = {id:1, name:'dd',age:32}; // 正确
函数类型 (参数名1:类型,参数名2:类型):输出定义
// 定义接口
interface MIF {
(sort: string, size: number): {id:number}[]
}
// 使用接口
let func : MIF;
// 定义函数(参数顺序与接口一致;但参数名可以不同)
func = (sort:string, size:number) =>[{id:1},{id:2}]; // 正确:参数顺序与参数名都一致
func = (order:string, length:number) =>[{id:1},{id:2}]; // 正确:参数顺序一致, 参数名可以不同
注:参数顺序必须与接口一致;但参数名可以不同
可索引类型 [idx:number] : 索引结果类型
数字索引
interface MIF {
[idx:number]:string
}
let arr :MIF;
arr = ['a','b','c','d'];
arr[2]; // 正确:输出'c'
字符串索引
interface MIF {
[index:string]:string
}
let obj :MIF;
obj = {name:'n'};
arr.name; // 正确:输出'n'
只读索引
interface MIF {
readonly [index:number]:string
}
let arr : MIF;
arr = ['a','b','c']
arr[1] = 'd'; // 错误:因为只读索引无法修改
类Class接口
interface MIF {
full_name:string;
setName(name:string);
}
class PERSON implements MIF {
full_name:string
setName(full_name:string){ this.full_name = full_name;}
constructor(first_name:string, last_name:string){
this.full_name = first_name + last_name
}
}
let p:MIF = new PERSON('W',"J");
p.setName('WanJin');
class类内部变量/方法分成成员与私有,
interface只能检测成员,不能检测私有
但是实例时的传参是传给contructor的,contructor是私有的,所以无法直接被interface检测
解决方法如下:
- 写类和类的接口,用来校验类的成员变量/方法
- 给实例化new专门写一个方法,在new以前,先把实例化时的参数进行校验
// class类的校验,用来校验类的成员属性与方法
interface MIF_class {
name:string;
getName();
}
// 类
class USER implements MIF_class{
constructor(name:string){
this.name = name;
}
name
getName(){}
}
//////// 以上只校验了class的成员属性/方法//////
//////// 以下用来校验实例时传给contructor的参数//////
// 参数是需要传给class的参数,
// 返回实例
interface MIF_creator {
new (name:string):MIF_class
}
// 生成实例的方法
function create_class(ctor:MIF_creator,name:string):MIF_class {
return new ctor(name)
}
console.log(create_class(USER,'WJ'))
接口继承 extends
interface MIF_person {
name:string
}
interface MIF_student{
student_id:number
}
interface MIF_champion extends MIF_person, MIF_student{
scores:number
}
let student : MIF_champion = {
name:'WJ',
student_id:11,
scores:100
}
接口继承类注意:接口继承的父级不是接口,是类
class C_Base {
private state: any;
}
// 接口MIF继承自!!!类!!!
// 注意:继承自类,而不是接口
// MIF继承CLASS_BASE后,会将CLASS_BASE的所有属性方法(私有/成员)都继承,并校验所有属性方法
// 最后的结果是:MIF会校验 select、state
interface MIF extends C_Base {
select(): void;
}
// 错误:因为C1内部没有state属性
class C1 implements MIF {
select() { }
}
// 正确:因为C2继承C_Base后,就有select和state,可以通过MIF校验
class C2 extends C_Base implements MIF {
select() { }
}
混合类型
// 接口描述的对象,本身是一个函数;
// 然后在函数上挂载了1个属性age,和一个方法setAge
interface MIF {
(name:string):string;
age:number;
setAge(age:number):void
}
// 对象student本身是函数
let student = <MIF>function (name:string) {
return 'My name is '+name;
}
// student上又挂载了属性age与方法setAge
student.age = 18;
student.setAge = function(age){return this.age = age;}
student('WJ')
student.setAge(24)
student.age
网友评论