0%

重新學習TS-六-TypeScript-Function

前言

來研究研究TS function && 與JS的差異


整理整理大致如下:

功能 TypeScript JavaScript
類型定義 可以提供參數和返回值的類型定義 沒有內建的類型定義,函數可以接受任何參數和返回任何值
靜態類型檢查 提供編譯時的類型檢查 沒有內建的靜態類型檢查,只能在運行時進行類型檢查
函式多載 可以使用函式多載來定義多個函數簽名 不支持函式多載,只能使用最後一個定義的函數簽名
可選參數和預設參數 可以定義參數為可選的或設置預設值 參數是必需的,但可以通過檢查參數的值進行類似的操作
函數型別推斷 提供更準確的函數型別推斷 型別推斷相對不準確,需要額外的註釋來明確型別
函數型別註釋 可以使用註釋明確指定函數的參數和返回值型別 可以使用JSDoc註釋來指定類型,但沒有內建的方式
this 的處理 支持更好的 this 綁定,可以在函數定義中指定 this 的類型 this 綁定規則相對較模糊,需要注意使用箭頭函數或額外綁定 this
函數型別作為參數和返回值的類型 函數型別可以作為參數和返回值的類型 函數型別也可以作為參數和返回值的類型,但沒有內建的型別檢查

Function 是甚麼

FunctionJavaScript 應用程序的基礎,幫助我們實現抽象層、模擬類、信息隱藏和模塊

TypeScript 裡,雖然已經支持類、命名空間和模塊,但Function仍然是主要定義行為的方式,

TypeScript為JavaScript Function添加了額外的功能,豐富了更多的應用場景

Function類型在TypeScript 類型系統中扮演著非常重要的角色,它們是可組合系統的核心構建塊

使用方式

javascript 定義函數十分相似,可以通過function 關鍵字、箭頭函數等形式去定義,例如下面一個簡單的加法函數:

1
const add = (a: number, b: number) => a + b

上述只定義了function的兩個參數類型,這個時候整個function雖然沒有被顯式定義,
但是實際上TypeScript 編譯器是能夠通過類型推斷到這個function的類型

當鼠標放置在add函數名的時候,會出現完整的函數定義類型,通過: 的形式來定於參數類型,通過=> 連接參數和返回值類型

當我們沒有提供函數實現的情況下,有兩種聲明函數類型的方式,如下所示

1
2
3
4
5
6
7
// 方式一
type LongHand = {
(a: number): number;
};

// 方式二
type ShortHand = (a: number) => number;

當存在函式多載時,只能使用方式一的形式

可選參數

當函數的參數可能是不存在的,只需要在參數後面加上? 代表參數可能不存在,如下:

1
const add = (a: number, b?: number) => a + (b ? b : 0)

這時候參數b可以是number類型或者undefined類型,即可以傳一個number類型或者不傳都可以

剩餘類型

剩餘參數與JavaScript的語法類似,需要用... 來表示剩餘參數

如果剩餘參數rest 是一個由number類型組成的數組,則如下表示:

1
const add = (a: number, ...rest: number[]) => rest.reduce(((a, b) => a + b), a)

函式多載(英語:function overloading)

允許創建數項名稱相同但輸入輸出類型或個數不同的子程序,它可以簡單地稱為一個單獨功能可以執行多項任務的能力

關於typescript函式多載,必須要把精確的定義放在前面,最後函數實現時,需要使用 |操作符 或者 ?操作符,把所有可能的輸入類型全部包含進去,用於具體實現

這裡的函式多載也只是多個函數的聲明,具體的邏輯還需要自己去寫,typescript並不會真的將你的多個重名function的函數體進行合併

例如我們有一個add函數,它可以接收string類型的參數進行拼接,也可以接收number 類型的參數進行相加,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 上面是聲明
function add (arg1: string, arg2: string): string
function add (arg1: number, arg2: number): number
// 因為我們在下面有具體函數的實現,所以這裡並不需要添加 declare 關鍵字

// 下面是實現
function add (arg1: string | number, arg2: string | number) {
// 在實現上我们要注意嚴格判断兩個参數的類型是否相等,而不能簡單的寫一個 arg1 + arg2
if (typeof arg1 === 'string' && typeof arg2 === 'string') {
return arg1 + arg2
} else if (typeof arg1 === 'number' && typeof arg2 === 'number') {
return arg1 + arg2
}
}

與JavaScript區別

從上面可以看到:

  • 從定義的方式而言,typescript 聲明函數需要定義參數類型或者聲明返回值類型
  • typescript 在參數中,添加可選參數供使用者選擇
  • typescript 增添函數多載功能,使用者只需要通過查看函數聲明的方式,即可知道函數傳遞的參數個數以及類型

References

你的支持是我活力的來源 :)