Interface
TS 中的核心概念,就是把 Javascript 中的弱语言类型变成强类型,也就是值进行类型检查。在TS中,一般有两种方式:一种是直接在变量初始化的时候就声明变量的类型,或者函数传参的时候在形参那里初始化类型。另外一种就是更加灵活的 Interface(接口)
Interface 定义了变量与类型的绑定关系,检测变量声明或者参数传参的合法性,并且可以更加灵活的校验参数传参的类型和个数。
最简单普通的一个Interface
interface value{name:string;}let value: value = {name:"qujun"}
接口也可以是一个函数类型
//函数类型的接口interface funInter {(name : string, age: number): void;}let myInfo: funInter;myInfo = (name : string, aa:number) =>{console.log(`${name},hi`)}myInfo('qu', 18)
当函数的参数为一个对象时 可以对参数进行额外的属性检查
interface inter {name? : string;age? : number;}const myInfo2 = function(myinfo:inter):void{ /**code*/ }myInfo2({name1:'qujun', age :18}); 会有如下提示myInfo2({name1:'qujun', age :18} as inter); // 不会有错误提示

上面说明了name1 不在inter 接口的定义当中,as inter 相当于做了一次类型断言,绕开了检测
或者修改 interface 让它可以添加任意数量的其他属性
interface inter {name? : string;age? : number;[propName: string]:any; // propName 必须为string 或 number(索引签名参数)}
上面的第四行 [propName: string]:any; 代码声明了一个 索引签名。
索引签名 :表示该接口下的参数以索引的类型返回对应类型的值
interface arrInter {[index:number]:string //索引返回的值是string}interface objInter {[index:string]:Number; //索引返回的值是numberlevel:Number; //参数的类型必须要跟索引返回值的类型一致age:Number;}let arr: arrInter = ["hello","world"]let obj: objInter = {level:20,age:18}let val:String = arr[0] //数字索引let val1:any = obj["name"] //字符串索引
可以给索引签名加上只读属性,意味着无法以索引的方式重新赋值
interface arrInter {readonly [index:number]:String}// 跟上面代码一致..arr[1] = '你好'//**ts会提示错误 :类型“arrInter”中的索引签名仅允许读取**arr = ["ni","hao"] //重新赋值是允许的
class Type
顾名思义 该接口是为类定义的一个类型集合 使用 implements 实现
interface classInter {name:String;age:Number;}class myInfo implements classInter {name:String;age: Number;constructor(name:String, age: Number){this.age = agethis.name = name}}
如果interface 下是new 出来是类型时, 意味着它是静态类型。class 类 在使用 implements 生成一个构造函数时,ts会报错。
interface constructorInter {new(name: string, age: string)}class myInfo implements constructorInter {name: string;age: number;constructor(name: string, age: number) {}}/*报错信息类“myInfo”错误实现接口“constructorInter”。类型“myInfo”提供的内容与签名“new (name: string, age: string): any”不匹配。ts(2420)*/
原因是 当一个类实现了一个接口时 只会检查它的实例部分, constructor 存在于静态部分 ,所以不会检查, 需要经过如下调整
interface constructorInter {new(name: string, age: number)}class myInfo {name: string;age: number;constructor(name: string, age: number) {}}const createInstance = function (cons: constructorInter, name: string, age: number) {return new cons(name, age)}createInstance(myInfo, 'qujun', 18)
接口继承
跟类一样,接口也可以进行继承
interface interSuper {name: string;}interface inter extends interSuper {age: number}let info = <inter>{}info.name = 'qujun';info.age = 18;
也可以继承多个接口
interface interName {name: string;}interface interAge {age: number;}interface inter extends interName, interAge {level: number}let info = <inter>{}info.name = 'qujun';info.age = 18;info.level = 66;
interface 也可以作为函数的返回值使用
interface interInfo {name: string;age: number;}function myInfo():interInfo {let info = <interInfo>{} //表示声明一个具有interInfo接口的空对象info.name ="qujun";info.age = 18return info;}
最后总结一下 Interface 可以为那些结构定义类型
- 普通对象
interface value{name:string;}
- 函数对象
interface funInter {(name : string, age: number): void;}
- 索引签名
interface arrInter {[index:number]:string}
- 实例对象
interface constructorInter {new(name: string, age: string)}
有关 type 的 一些用法
type str = string;type strResolve = () => string;type strOrResolve = str | strResolve;const fn = (n:strOrResolve) => {if(typeof n == 'string'){return n}else{return n()}}fn('str')const strFn = () => {return 'hello world'}fn(strFn)
type str<T extends string> = T; // 声明一个function MyFn(name:str<string>){return name}MyFn('qujun')
type Tvalue<T> = {value:T}const fn1 = (param : Tvalue<string>) => {// 只对参数负责,并不对函数的返回值负责return param.value.split['']}fn1({value:'qujun'})
type Tree<T> = {value: T;left?: Tree<T>;right?: Tree<T>;};const fn2 = (tree: Tree<string>) => {return tree.value;};const mockTree = {value: "0",left: { value: "01" },right: { value: "02" },};fn2(mockTree);
