TypeScript真香系列的内容将参考中文文档,可是文中的例子基本不会和文档中的例子重复,对于一些地方也会深刻研究。另外,文中一些例子的结果都是在代码没有错误后编译为JavaScript获得的。若是想实际看看TypeScript编译为JavaScript的代码,能够访问TypeScript的在线编译地址,动手操做,印象更加深入。javascript
TypeScript的核心原则之一是对值所具备的结构进行类型检查。 它有时被称作“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的做用就是为这些类型命名和为你的代码或第三方代码定义契约。能够说接口的出现,可让咱们在开发之中发现并避免许多问题的出现,提升咱们的开发效率。java
在面向对象编程中,接口是一种规范的定义,它定义了行为和动做的规范。以下面的例子:git
interface IDo { work:string; time:number; } interface IMan { age:number; name:string; do:IDo; } let james: IMan = { name: 'james', age: 35, do: { work: 'player', time: 2020 } } james.name; //"james" james.do.work; //"player"
若是咱们在james中把name的类型写成数字12,也就是number类型,或者没有写age。那么就会出现错误提示。github
在咱们开发中,接口中的属性有时候也不全都是必要的,在有些条件下存在,有些条件下又是不存在的。typescript
interface IMan { age?:number; name:string; } let james: IMan = { name:"james" }
一些对象属性只能在对象刚刚建立的时候修改其值。编程
interface IMan { age:number; readonly name:string; } let james: IMan = { name:"james", age:35 } james.name = "mike"; // error: Cannot assign to 'name' because it is a read-only property.
在咱们可以肯定一个对象可能具备某些作为特殊用途使用的额外属性时,最佳的方式是可以添加一个字符串索引签名。数组
interface IMan { age:number; readonly name:string; [propName: string]: any; } let james: IMan = { name:"james", age: 35, work:"player" }
函数也是对象,相似的咱们能够用接口表示函数的类型。函数
interface IFunc { (x: string, y: string): string; } let func: IFunc = function(x: string, y: string){ return x + y; } func("1", "!"); // "1!"
对于函数类型的类型检查来讲,函数的参数名不须要与接口里定义的名字相匹配。this
interface IFunc { (x: string, y: string): string; } let func: IFunc = function(a: string, b: string){ return a + b; } func("1", "!"); // "1!"
可用于数组和对象的约束。code
interface IMan { [index:number]:string } //数组 let man1: IMan; man1 = ["james", "wade", "bosh"]; //对象 let man2: Man; man2 = {1:"haha", 2:"666"}; console.log(man1); //["james", "wade", "bosh"] console.log(man2); //{1: "haha", 2: "666"}
TypeScript也可以用接口来明确的强制一个类去符合某种规定,能够用implements来实现。
interface IMan { name:string; play(val:string):void; } class IFootballer implements IMan { name:string constructor(name:string){ this.name = name } play(val:string){ console.log(this.name + '踢'+ val) } } class IBasketballer implements IMan { name: string constructor(name:string){ this.name = name } play(val:string){ console.log(this.name + '打'+ val) } } var a = new Footballer('武磊') a.play("足球") //武磊踢足球 var b = new Basketballer ('姚明') b.play("篮球") //姚明打篮球
和咱们的类同样,接口之间也能够相互继承。
interface IMan { name: string; } interface IPlayer extends IMan { types:string } class IFootballer implements IPlayer { name: string; types: string; constructor(name:string, types:string){ this.name = name; this.types = types } play(){ console.log(this.name+ "是" + this.types) } } let a = new Footballer("c罗", "足球运动员"); a.play(); //c罗是足球运动员
一个接口也能够继承多个接口,中间用逗号分隔。
interface IMan { name: string; } interface ICity { city:string; } interface IPlayer extends IMan,ICity { types:string }
混合类型
咱们可让一个对象同时具备多种类型。
interface ICounter { (start: number): string; interval: number; reset(): void; } function getCounter(): ICounter { let counter = <ICounter>function (start: number) { }; counter.interval = 123; counter.reset = function () { }; return counter; } let c = getCounter(); c(10); c.reset(); c.interval = 5.0;
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了全部类中存在的成员,但并无提供具体实现同样。 接口一样会继承到类的private和protected成员。 这意味着当你建立了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。
当咱们有一个庞大的继承结构时这颇有用,但要指出的是咱们的代码只在子类拥有特定属性时起做用。 这个子类除了继承至基类外与基类没有任何关系。
class Control { private state: any; } interface ISelectableControl extends IControl { select(): void; } class Button extends Control implements ISelectableControl { select() { } } class TextBox extends Control { select() { } } // 错误:“Image”类型缺乏“state”属性。 class Image implements ISelectableControl { select() { } } //error class Location { }
https://github.com/zhongsp/Ty...
文中有些地方可能会加入一些本身的理解,如有不许确或错误的地方,欢迎指出~祝你们新年快乐,阖家辛福!但愿前线的医护人员健健康康,早日战胜病毒!但愿你们都健健康康!