TS的接口好像C#/Java中的接口 , 但是TS的interface是不能继承(implement)其他的interface , 但是TS的interface可以规范自己的结构Object.无论如何TS比起JS来说,在OOP上面进步了不少.

注 : 下面的代码都是TS代码 


/** * Created by CV-PC153 on 2017/8/7. */interface User{    id:number;    name:string;}function greeter(user:User):string{    return `No.${user.id}, name is :${user.name}`;}let myObj : User = { id : 1 ,name : "Aonaufly" };document.body.innerHTML = greeter(myObj);

运行结果:

这里有一个奇怪的现象:

/** * Created by CV-PC153 on 2017/8/7. */interface User{    id:number;    name:string;}function greeter(user:User):string{    return `No.${user.id}, name is :${user.name}`;}let myObj = { age : 1 ,id : 1 ,name : "Aonaufly"};document.body.innerHTML = greeter(myObj);

以上代码 , 去掉了myObj的类型 , 并且加上了一个age : 1 依然可以得到一个正确的结果.

继续更改在greeter方法中打印出user.age , 会报错: 

结果编译报错:

很有意思 , 可以给个总结 :

object 没有强制指定是interface(上文中的User)类型的话 , 只要它包含了User所有属性,它任然可以当做User使用.方法中的参数,如果被限定为interface(上文中的User),那此方法只能使用interface限定的方法.反之若参数不限制:

/** * Created by CV-PC153 on 2017/8/7. */interface User{    id:number;    name:string;}function greeter(user:any):string{    return `No.${user.id}, name is :${user.name} , age : ${ user.age }`;}let myObj = { age : 1 ,id : 1 ,name : "Aonaufly"};document.body.innerHTML = greeter(myObj);

结果如下:

但这样显然又不符合OOP的思想了.

可选属性: (?符号 如 age?:number 那么age就是一个可选属性),顾名思义,继承者可选属性赋值

/** * Created by CV-PC153 on 2017/8/7. */interface User{    id:number;    name:string;    age?:number;}function greeter(user:User):string{    return `No.${user.id}, name is :${user.name} , age : ${ user.age }`;}let myObj:User = { id : 1 ,name : "Aonaufly"};document.body.innerHTML = greeter(myObj);

结果:

所以 , 可选属性有时候比较坑.你可能想显示age信息,结果忘了在myObj中定义,也不会报错.如下代码:

/** * Created by CV-PC153 on 2017/8/7. */interface User{    id:number;    name:string;    age?:number;}function greeter(user:User):string{    return `No.${user.id}, name is :${user.name} , age : ${ user.age }`;}let myObj:User = { id : 1 ,name : "Aonaufly" , age:1};document.body.innerHTML = greeter(myObj);

如果定义了可选属性,一定要注意.

在interface中申明函数:

/** * Created by CV-PC153 on 2017/8/7. */interface TalkPro{    name : string;    content : string;}interface SayFunc{    (talk : TalkPro):string;}let iSay : SayFunc;iSay = function(talk :TalkPro):string{    return `${talk.name}:${talk.content}`;}function greeter( func :  SayFunc , talk : TalkPro ):string{    return func(talk);}let i_went_talk : TalkPro = { name:"Aonaufly" , content:"interface SayFunc is like C# at statement function" };document.body.innerHTML = greeter(iSay,i_went_talk);

SayFunc申明了一个方法 , 得到结果:

可索引的类型

数字索引的返回值必须是字符串索引返回值类型的子类型

类继承接口(动态性多态)

/** * Created by CV-PC153 on 2017/8/7. */interface TalkPro{    name : string;    content : string;}interface SayClass{    toTalk( ):string;}interface SayCtor{    new( msg : TalkPro ) : SayClass;}class Chinese implements SayClass{    private msg : TalkPro;    constructor( msg : TalkPro ){        this.msg = msg;    }    toTalk( ):string{        return `[Chinese] ${this.msg.name}:${this.msg.content}`;    }}class USA implements SayClass{    private msg : TalkPro;    constructor( msg : TalkPro ){        this.msg = msg;    }    toTalk( ):string{        return `[USA] ${this.msg.name}:${this.msg.content}`;    }}function create_sayClass( ctor : SayCtor , msg : TalkPro ) : SayClass {    return new ctor( msg );}let chinese_ : TalkPro = { name:"Aonaufly" , content:"ni hao!" };let usa_ : TalkPro = { name:"Polo" , content:"hello!" };let cla_chinese : SayClass = create_sayClass( Chinese , chinese_);let cla_usa : SayClass = create_sayClass( USA , usa_);function greeter( saycl : SayClass ):string{    return saycl.toTalk();}document.body.innerHTML = greeter(cla_usa);

结果: