考慮以下JavaScript函式(myText):

/// <reference path="../Scripts/jquery-2.1.1.js" />
 
function myText(selector, valueOrFunction) {
    //未指定第二個參數時,傳回jQuery .text()
    if (valueOrFunction === undefined) {
        return $(selector).text();
    }
    //第二個參數可以是數值或函式,如為函式則呼叫取值
    var value = $.isFunction(valueOrFunction) ?
                valueOrFunction() : valueOrFunction;
    $(selector).text(value);
}
 
 
$(function () {
    var src = myText("#src")
    $("#t1").text(src);
    myText("#t2", "Given by Value");
    myText("#t3", function () {
        return "Given by Function: " + parseInt(Math.random() * 10000);
    });
});

myText的傳入參數selector及valueOrFunction具有彈性: 當valueOrFunction未提供時會傳回jQuery(selector).text();valueOrFunction有值時使用jQuery(selector).text(...)設定元素的文字內容,valueOrFunction可以是字串或函式,如果是函式則由呼叫函式動態取得字串。

若以C#觀點,myText()方法有三個多載(Overloading),分別是myText(string selector)、myText(string selector, string value)及myText(string selector, Func<stirng> func)。 在TypeScript,我們也能實現類似的函式Overloading效果,將以上的函式改寫成TypeScript: (註: 嚴格來說,TypeScript多載與C#並不完全相同,C#多載的傳回型別必須一致)

/// <reference path="../scripts/typings/jquery/jquery.d.ts" />
 
/** 
    * 取得jQuery .text() 
    * @param selector jQuery選擇器字串
    */
function myText(selector: string): string;
/** 
    * 使用jQuery .text()設定文字內容
    * @param selector jQuery選擇器字串
    * @param value 要設定的字串內容
    */
function myText(selector: string, value: string):void;
/** 
    * 使用jQuery .text()設定文字內容
    * @param selector jQuery選擇器字串
    * @param func 函式,傳回待設定內容
    */
function myText(selector: string, func: () => string): void;
function myText(selector: string, valueOrFunction?: any) {
    if (valueOrFunction === undefined) {
        return jQuery(selector).text();
    }
    var value: string = jQuery.isFunction(valueOrFunction) ?
        valueOrFunction() : valueOrFunction;
    jQuery(selector).text(value);
}
 
jQuery(function () {
    var src = myText("#src")
    $("#t1").text(src);
    myText("#t2", "Given by Value");
    myText("#t3", function () {
        return "Given by Function: " + (Math.random() * 10000).toFixed(0);
    });
});

我們宣告三個沒有內容的函數宣告:

function myText(selector: string): string;
function myText(selector: string, value: string):void;
function myText(selector: string, func: () => string): void;

其中第三個用Lambda語法指定func參數型別需為一個傳回字串的函式。最後的function myText(selector: string, valueOrFunction?: any)提供真正的實做,由於valueOrFunction參數可有可無,要寫為"valueOrFunction?",否則function myText(selector: string)會無法對應。

以上的TypeScript會轉換成如下的JavaScript:

/// <reference path="../scripts/typings/jquery/jquery.d.ts" />
 
 
function myText(selector, valueOrFunction) {
    if (valueOrFunction === undefined) {
        return jQuery(selector).text();
    }
    var value = jQuery.isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;
    jQuery(selector).text(value);
}
 
jQuery(function () {
    var src = myText("#src");
    $("#t1").text(src);
    myText("#t2", "Given by Value");
    myText("#t3", function () {
        return "Given by Function: " + (Math.random() * 10000).toFixed(0);
    });
});
//# sourceMappingURL=typescript.js.map

最前方三個額外函式宣告不會在JavaScript中出現,但會在編輯及編譯階段發揮Strong Type的威力:

首先,打入myText(時,Intellisense會像C#一樣列舉三個多載選擇,透過JSDoc,函式及參數都有中文說明。

故意寫了四行不符型別的myText()呼叫方式,通通被打槍標上紅蚯蚓:

  • myText(2) <== selector不能是number
  • var i: number = myText("#t1") <== 傳回值必須用字串變數承接
  • myText("#t1", 5) <== 沒有第二個參數為number的overloading
    注意: 宣告多載時,實做函式myText(selector: string, valueOrFunction?: any)不納入多載選項。
  • myText("#t1", () => { return 6; }); <== 第二參數雖然是函式,但傳回值不是string而是number
    註: () => { return 6; } 相當於 function() { return 6; },在TypeScript可以用Lambda寫匿名函式。

很嚴謹很機車吧? 愈機車愈是深得我心,不愧為錯字天王的救星~


Comments

Be the first to post a comment

Post a comment