TS新增了一个重要概念:接口,分为对象类型接口和函数类型接口
接口能够约束对象,函数,类的结构和类型,是一种代码协做必须遵照的契约
接口的定义方式:后端
使用interface关键字
对象类型接口
接口中可定义 肯定属性、可选属性、任意属性、只读属性数组
interface UserInfo { name: string; age: number; } const myInfo: UserInfo = { name: "haha", age: 20 };
接口中约束好的肯定属性,定义对象变量的时候 不能少也 不能多函数
二、可选属性spa
interface UserInfo {
name: string;
age: number;
sex?:string
}
const myInfo: UserInfo = {
name: "haha",
age: 20
};
接口中的可选属性,是表示在对象变量中能够不存在code
三、任意属性对象
interface UserInfo {
name: string;
age: number;
sex?:string ;
[propName: string]:any;
}
const myInfo: UserInfo = {
name: "haha",
age: 20,
test1: 'lala',
test2: 'ff',
test3:123
};
注:一旦定义了任意属性,那么肯定属性和可选属性的类型都必须是任意属性类型的子类;blog
定义了任意属性后,对象变量中的属性个数才能够出现比接口的属性数量多的状况索引
四、只读属性接口
interface UserInfo {
readonly id: number;
name: string;
age: number;
sex?: string;
[propName: string]: any;
}
const myInfo: UserInfo = {
id: 1,
name: "haha",
age: 20,
test1: "lala",
test2: "ff",
test3: 123
};
只读属性也是肯定属性,在对象变量定义的时候必须有值,此后不能修改ip
以查询商品列表接口API为例:
// 接口声明:API协议约定返回格式 interface ResponseData { resCode: number; resData: ResultData[]; message: string; } // 数据接口声明 interface ResultData { productId: number; productName: string; }
符合接口约定的对象:
let resultData = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战" }, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" }
输出函数对结果进行打印:
function render(res: ResponseData) { console.log(res.resCode, res.message) res.resData.forEach((obj) => { console.log(obj.productId, obj.productName) }) } render(resultData);
输出:
0 "success" 1 "TypeScipt实战" 2 "TypeScipt从入门到精通"
额外属性
在接口的实际调用中,后端也常常会传递约定以外的字段,好比:
let resultData = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark:""}, // 接口约定之外的remark字段 { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" }
此时,并无报错,TS容许这种状况的发生
只要传入的对象知足接口的必要条件就能够被容许,即便传入多余的字段也能够经过类型检查
但也有例外,若是直接传入对象字面量,TS就会对额外的字段进行类型检查
如下方式会报错:
render({
resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark: "备注"}, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" })
绕过检查的方法有3种:
将对象字面量赋值给一个变量后,在render再也不报错:
let result = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark: "备注"}, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" } render(result)
使用类型断言方式,明确告诉编译器类型是什么,编译器就会绕过类型检查
方法1:
object as targetInterface
render({ resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark:""}, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" } as ResponseData)
方法二:
<targetInterface>object
render(<ResponseData>{ resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark: "备注"}, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" })
添加字符串索引签名:
interface ResultData { productId: number; productName: string; [remark: string]: any; // 字符串索引签名 }
表示用任意字符串去索引List,可获得任意结果,此时List能够实现支持多个属性
1,在TS中,可使用一个变量直接定义函数:
// 1,使用变量定义函数 let add: (x: number, y: number) => number
= (x, y){
return x+y; };
add(1,2)
2,还可使用接口来定义函数:
// 2,使用接口定义函数 interface Add { (x: number, y: number): number }
let myFunc: Add = function(x, y){ return x+y; }; myFunc(1,2);
3,使用类型别名来定义函数:
类型别名使用type关键字,至关于为函数类型起一个名字
// 3,使用类型别名来定义函数 type Add = (x: number, y: number) => number
当不能肯定接口中有多少个属性时,可使用可索引类型接口 可索引类型接口能够用数字去索引,也能够用字符串去索引
声明一个数字索引类型的接口:
表示用任意数字去索引numberIndex都会获得一个string
interface numberIndex { [x: number]: string } // 至关于声明了一个字符串类型的数组 let chars: numberIndex = ['A', 'B']
声明一个字符串索引类型的接口:
表示用任意的字符串去索引stringIndex获得的结果都是string
interface stringIndex {
[x: string]: string
}
这样声明后,就不能声明number类型的成员了,会报错
interface stringIndex { [x: string]: string y: number;// Property 'y' of type 'number' is not assignable to string index type 'string'. }
在上边的字符串索引接口stringIndex中,添加数字索引签名
interface stringIndex {
[x: string]: string
[z: number]: string
}
这样作.接口既能够用数字索引Names也能够用字符串索引Names
但须要注意:数字索引的返回值,必定要是字符串返回类型的子类型
这是由于JS会进行类型转换,将number转换成string,这样就能保证类型的兼容性
好比:将数组索引的返回值改为number:
interface stringIndex { [x: string]: string [z: number]: number // // Numeric index type 'number' is not assignable to string index type 'string'. }
这样就和String类型不兼容了,要取一个可以兼容number的类型,好比any:
interface stringIndex { [x: string]: any [z: number]: number // Numeric index type 'number' is not assignable to string index type 'string'. }