1. 程式人生 > >TypeScript 接口

TypeScript 接口

typescript 接口

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);

結果:

技術分享

本文出自 “Better_Power_Wisdom” 博客,請務必保留此出處http://aonaufly.blog.51cto.com/3554853/1954600

TypeScript 接口