本系列目的: 列出TypeScript與JavaScript的不同點, 縮小文件內容, 提高學習速度. 原文件地址: https://www.tslang.cn/index.html

函式

簡單使用

// 虛擬碼例子
函式名(引數: 型別): 返回值 {

}

// 例1
function add(x: number, y: number): number {
    return x + y;
}


// 例2 完整函式型別
let myAdd: (x2: number, y3: number) => number =
    function(x: number, y: number): number { return x + y; }; // 只要引數型別匹配就可以, 引數名無所謂

// 例3 如果聲明瞭完整函式型別, 後面的型別可以省略
let myAdd: (baseValue: number, increment: number) => number =
    function(x, y) { return x + y; };
    

引數

可選引數

和js不同的是, typescript函式在是使用時所傳入的引數要符合所定義時的引數數量及型別. 那麼我們可以使用?, 實現可選引數.(可選引數必須跟在必須引數後面)

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // error, 引數太少
let result2 = buildName("Bob", "Adams", "Sr.");  // error, 引數太多
let result3 = buildName("Bob", "Adams");         // ok


----------------------------------------------


function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");  // ok
let result2 = buildName("Bob", "Adams", "Sr.");  // error, 引數太多
let result3 = buildName("Bob", "Adams");  // ok

預設引數

預設引數和js一致, 並且預設引數與可選引數一樣,在呼叫函式的時候可以省略. 與普通可選引數不同的是,帶預設值的引數不需要放在必須引數的後面。 如果帶預設值的引數出現在必須引數前面,使用者必須明確的傳入 undefined值來獲得預設值.(這點也與js保持一致)

function buildName(firstName: string, lastName = "Smith") {
    // ...
}

剩餘引數

剩餘引數可以採用es2015的rest運算子的形式使用. 例:

function buildName(firstName: string, ...restOfName: any[]) {
  return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie", 12, {gkd: 'gkd'});

this

typescript中可以限制this物件, 如下面的例子

// his引數是個假的引數,它出現在引數列表的最前面:
function f(this: void) {
    // 這麼定義的話, 這個f函式內部無法使用this, 因為this的型別為void
}


-----------------------------------


// 詳細用法
interface Card {
    suit: string;
    card: number;
}
interface Deck {
    suits: string[];
    cards: number[];
    createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    // 該函式現在顯式指定其被呼叫者必須是Deck型別
    createCardPicker: function(this: Deck) {
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

函式過載

和c++語言的過載不同的是, 只有一個處理函式, 如下面的例子:

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // 檢查引數是物件還是數字
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);