一、函數類型
-
定義函數類型
// 函數式聲明 function add(x: number, y: number): number { return x + y; } // 由變量指向的匿名函數 let myAdd = function(x: number, y: number): number { return x + y; }; -
完整函數類型
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };通常需要將類型抽離成接口,形成規范。
-
推斷類型
函數定義賦值語句一邊有類型。
// myAdd has the full function type let myAdd = function(x: number, y: number): number { return x + y; }; // The parameters `x` and `y` have the type number let myAdd: (baseValue: number, increment: number) => number = function(x, y) { return x + y; };
二、可選參數、默認參數
? ts中傳遞給一個函數的參數個數必須與函數期望的參數個數一致。
-
可選參數
在TypeScript里我們可以在參數名旁使用
?實現可選參數的功能。function buildName(firstName: string, lastName?: string) { if (lastName) return firstName + " " + lastName; else return firstName; } let result1 = buildName("Bob"); // works correctly now let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters let result3 = buildName("Bob", "Adams"); // ah, just right注意:可選參數必須跟在必須參數后面。
-
默認參數
在TypeScript里,我們也可以為參數提供一個默認值當用戶沒有傳遞這個參數或傳遞的值是
undefined時。 它們叫做有默認初始化值的參數。function buildName(firstName: string, lastName = "Smith") { return firstName + " " + lastName; } let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith" let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith" let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters let result4 = buildName("Bob", "Adams"); // ah, just right在所有必須參數后面的帶默認初始化的參數都是可選的,與可選參數一樣,在調用函數的時候可以省略。
function buildName(firstName: string, lastName?: string) { // ... } function buildName(firstName: string, lastName = "Smith") { // lastName為可選,調用時可省略 // ... }與普通可選參數不同的是,帶默認值的參數不需要放在必須參數的后面。 如果帶默認值的參數出現在必須參數前面,用戶必須明確的傳入
undefined值來獲得默認值。 例如,我們重寫最后一個例子,讓firstName是帶默認值的參數:function buildName(firstName = "Will", lastName: string) { return firstName + " " + lastName; } let result1 = buildName("Bob"); // error, too few parameters let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters let result3 = buildName("Bob", "Adams"); // okay and returns "Bob Adams" let result4 = buildName(undefined, "Adams"); // okay and returns "Will Adams" 首個參數后有其他參數,則要取得默認值必須要傳入undefined -
剩余參數
剩余參數會被當做個數不限的可選參數。
function buildName(firstName: string, ...restOfName: string[]) { return firstName + " " + restOfName.join(" "); } let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie"); -
this
JavaScript里,
this的值在函數被調用的時候才會指定。let deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), createCardPicker: function() { return function() { 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); // error 找不到this箭頭函數能保存函數創建時的
this值,而不是調用時的值。let deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), createCardPicker: function() { // NOTE: the line below is now an arrow function, allowing us to capture 'this' right here 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); -
重載
方法是為同一個函數提供多個函數類型定義來進行函數重載。
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 { // Check to see if we're working with an object/array // if so, they gave us the deck and we'll pick the card if (typeof x == "object") { let pickedCard = Math.floor(Math.random() * x.length); return pickedCard; } // Otherwise just let them pick the card 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);為了讓編譯器能夠選擇正確的檢查類型,它與JavaScript里的處理流程相似。 它查找重載列表,嘗試使用第一個重載定義。 如果匹配的話就使用這個。 因此,在定義重載的時候,一定要把最精確的定義放在最前面。(大幾率事件)
浙公網安備 33010602011771號