这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战”
接口
- 接口用来描述使用这个接口的对象需要满足接口中定义的要求,*类型检查器不会检查这些属性的顺序。
- 接口和类型在字面上很相似,接口规范了种类型,接口应该用大写字母开头,篇一种的大写字母的类型,
String...,都是规范JS原生对象的接口。
定义接口 和 基本使用
- 定义接口
interface Value { key1: number, key2: number } interface ResValue { key1: string, key2: string } - 使用接口
function numberToString(obj: Value): ResValue { return {key1: obj.key1.toString(), key2: obj.key2.toString()} } let val1: Value val1 = { key2: 15, key1: 'string' // 不能将类型“string”分配给类型“number”。 }
使用接口规范函数
- 接口用来规范函数,形参名不必相同,函数的参数会逐个进行检查,要求对应位置上的参数类型是符合的。
// 定义 interface NumberToStringFn { (prams1: number ): string } // 使用 let numberToString: NumberToStringFn numberToString = function(number) { return number.toString() }
可索引类型
- Javascript中对象的键实际上都是字符串类型,现在还有了Symbol类型,[]语法中使用对象,数子等都会自动调用toString()方法。
- 可索引类型可以使用数字和字符串,可以同时使用,当时由于
obj[1] = 1实际是obj['1'] = 1,所以字符串索引规定了全部的类型,数字索引仅规定了数字索引的类型,又因为obj[1]因满足obj['1'],所以数字索引的返回值类型必须是字符串索引类型的子类型,也就是能通过字符串索引规定类型的类型检查。interface Dic{ [index: number]: number, [index: string]: Object, } let a: Dic a[1] = 1 a['2'] = new Object - 下面这个写发会报错原因是这种写发非索引操作,ts会认为接口中描述的是对象任意属性被定义为number 且 键必须是number类型
let b: Dic = { // 不能将类型“{ 1: number; '2': Object; }”分配给类型“Dic”。 // 属性“'2'”与索引签名不兼容。 // 不能将类型“Object”分配给类型“number”。 1: 1, '2': new Object } - 可索引类型的只读设置和注意事项:设置后不可通过这种方式修改,如果只设置一种,在所束缚的是对象时,可通过字符串的方式修改,因为这里仅仅定义了数字类型索引。
interface Dic{ readonly [index: number]: string, } // let a: Dic // a[1] = 1 // a['2'] = new Object let a: Dic = ['0','1','2'] let b: Dic = {0:'0',1:'2',2:'2'} b['0'] = '3' // 无错误 a['0'] = '3' // 无错误 b[0] = '3' // 类型“Dic”中的索引签名仅允许读取。 a[0] = '3' // 类型“Dic”中的索引签名仅允许读取。
描述类
- 检查类时只会检查实例部分,静态部分不会检查
interface ClockInterface { // 用来描述类的接口 ClassName: string, // 描述实例属性 date: Date, // 描述实例属性 getTime(): string //描述原型方法 setTime(date: Date): void //描述原型方法 } class Clock implements ClockInterface { ClassName: 'Clock' date: Date constructor(date: Date){ // 描述构造函数参数 this.date = date || new Date() } getTime() { return this.date.toString() } setTime(date: Date) { this.date = date } }
继承接口
- 可以某个接口 继承 另一个接口的所有描述
interface A { a: string; } interface B { b: number; } interface C extends A, B { c: boolean; } let c: C c = { a: 'a', b: 1, c: true }
混合类型
- 描述对象的不同使用方法时的类型检查
interface _$$ { (fn?: Function) // 描述被调用时 name: string getName: () => string } let $ = (function(): _$${ const $ = function(fn){ fn&&fn() } $.getName = function(){ return $.name } $.name = '$' return $ })() $(function(){console.log('fn()')}) $.getName() $.name = '$$$'
接口继承类
- 接口会继承到类的 private 和 protected 成员
- 继承类的接口类型只能用来约束这个类或这个类的子类
class Control { private state: any; } interface SelectableControl extends Control { // 继承了 Control 类 select(): void; } class Button extends Control implements SelectableControl { select() { } } class TextBox extends Control { select() { } } // 非接口继承的类使用这个接口 会出现 没有 Control 类的相关属性 class Image implements SelectableControl { select() { } }