TypeScript里面的接口就是为了我们的变量类型或者代码做一些契约
function printLabel(labelObj: {label:string}) { console.log(labelObj.label)//Size 10 object } let myObj = { size: 10, label: 'Size 10 object' } printLabel(myObj) //改成接口类型的 interface labeldValue { label: string } function printLabel(labelObj: labeldValue) { console.log(labelObj.label)//Size 10 object } let myObj = { size: 10, label: 'Size 10 object' } printLabel(myObj)
接口里面的可选属性
interface Square { color: string area: number } interface SquareConfig { color?: string//?表示这个参数是可选的 width?: number } function createSquare(config: SquareConfig): Square { let newSquare = {color: 'white', area: 100} if (config.color) { //因为参数是可选的,所以要做判断. //这样做的好处是,如果config.color拼错了就会提示 newSquare.color = config.color } if (config.width) { newSquare.area = config.width * config.width } return newSquare } let mySquare = createSquare({color: 'black'}) console.log(mySquare)//{ color: 'black', area: 100 }
只读属性
interface Point { readonly x: number readonly y: number } let p1: Point = {x: 10,y: 20}//创建完以后就不能改变了 // p1.x = 6 //报错,因为是常数或者是只读属性
typeScript泛型只读数组
let a: number[] = [1, 2, 3, 4] let ro: ReadonlyArray<number> = a //ro[0] = 12//报错 //ro.push()//不存在属性push //可以使用类型断言 a = ro as number [] //和const的区别,const是作为一个变量,readonly是作为一个属性
额外属性检查
上述第一个例子中我们多传了一个size字面量属性,并没有报错,因为传入了label值,符合预期
interface Square { color: string, area: number } interface SquareConfig { color?: string,//?表示这个参数是可选的 width?: number } function createSquare(config: SquareConfig): Square { let newSquare = {color: 'white', area: 100} if (config.color) { //因为参数是可选的,所以要做判断. //这样做的好处是,如果config.color拼错了就会提示 newSquare.color = config.color } if (config.width) { newSquare.area = config.width * config.width } return newSquare } let mySquare = createSquare({colorr: 'black', 100}) //这里我们的color拼错了 //这里报错,因为这里color是一个对象字面量,typeScript会对这种字面量做检查 //一旦发现传入的属性不在定义的属性当中就会报一个错误 //解决方式1 类型断言 //这种方式并不好 //let mySquare = createSquare({colorr: 'black', 100} as SquareConfig) //解决方式2 添加一个字符串的签名索引,前提是确定这个对象会有额外的属性 // interface SquareConfig { // color?: string//?表示这个参数是可选的 // width?: number // [propName: string]: any // } //解决方式3 放入一个变量里 //let squareOptions = {colorr: 'black', 100} //let mySquare = createSquare(squareOptions)//这样会跳过检查 //真正的如果我们要使用colorr,应该加入inteface里面
接口描述函数类型
interface SearchFunc { (source: string, subString: string): boolean } let mySearch: SearchFunc mySearch = function (src: string, sub: string): boolean { let result =src.search(sub) return result > -1 } //也可以这样写 // mySearch = function (src, sub): boolean { // //不写参数类型,让TypeScript自行做推断 // let result =src.search(sub) // return result > -1 // }
可索引的类型
interface StringArray { [index: number]: string } let myArray: StringArray myArray = ['Bob', 'Raze'] let myStr: string = myArray[0] console.log(myStr)//Bob
类类型
//类的接口 //这里实现的实例类型的接口 //constructor是一个静态类型的接口 interface ClockInterface { currentTime: Date setTime(d: Date) } class Clock implements ClockInterface { currentTime: Date constructor(m: number,h:number ) { } setTime(d: Date) { this.currentTime = d } } //编译后 var Clock = /** @class */ (function () { function Clock(m, h) { } Clock.prototype.setTime = function (d) { this.currentTime = d; }; return Clock; }());
构造器接口
interface ClockConstructor { new(hour: number, minute: number )//构造器接口 }
什么时候该使用构造器接口(类的静态类型),什么时候使用实例接口呢
interface ClockInterface { tick() } interface ClockConstructor { new(hour: number, minute: number ): ClockInterface //返回值为构造器实例接口类型 } function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface{ //传入一个构造器ctor,传入构造器的参数hour,minute,返回值类型为实例接口类型 return new ctor(hour, minute) } class DigitalClock implements ClockInterface { constructor(h: number, m: number) { } tick(){ console.log('beep beep') } } class AnalogClock implements ClockInterface { constructor(h: number, m: number) { } tick(){ console.log('tik tok') } } let digital = createClock(DigitalClock,12, 17) let analog = createClock(AnalogClock,10, 10) digital.tick()//beep beep analog.tick()//tik tok
编译后的代码
function createClock(ctor, hour, minute) { //传入一个构造器ctor,传入构造器的参数hour,minute,返回值类型为实例接口类型 return new ctor(hour, minute); } var DigitalClock = /** @class */ (function () { function DigitalClock(h, m) { } DigitalClock.prototype.tick = function () { console.log('beep beep'); }; return DigitalClock; }()); var AnalogClock = /** @class */ (function () { function AnalogClock(h, m) { } AnalogClock.prototype.tick = function () { console.log('tik tok'); }; return AnalogClock; }()); var digital = createClock(DigitalClock, 12, 17); var analog = createClock(AnalogClock, 10, 10); digital.tick(); analog.tick();
继承接口
interface Shape { color: string } interface PenStroke { penWidth: number } interface Square extends Shape, PenStroke { sideLength: number } let square = {} as Square square.color = 'blue' square.sideLength = 10 square.penWidth = 5.0
混合类型
interface Counter { (start: number): string //函数签名 interval: number //对象属性 reset(): void } function getCounter(): Counter { let counter = (function(star:number) { }) as Counter counter.interval = 123 counter.reset = function () { } return counter } let c = getCounter() c(10) c.reset() c.interval = 5.0
编译后
function getCounter() { var counter = (function (star) { }); counter.interval = 123; counter.reset = function () { }; return counter; } var c = getCounter(); c(10); c.reset(); c.interval = 5.0;
接口继承类
class Control { private state: any } interface SelectControl extends Control { select() } class Button extends Control implements SelectControl { select(){} } class TextBox extends Control { select(){} //虽然没有实现SelectCntrol,仍然可以定义select()方法 } // class ImageC implements SelectControl { // //报错imageC缺少属性state // select(){} // }
2019-05-24 15:10:34