著手學習 TypeScript
請支持這本書:購買捐款
(廣告,請不要封鎖。)

2 為何使用 TypeScript?



如果您已經確定要學習並使用 TypeScript,可以跳過本章節。

如果您仍不確定,本章節是我的銷售推廣。

2.1 使用 TypeScript 的好處

2.1.1 更多錯誤在靜態中偵測到(無需執行程式碼)

在整合開發環境中編輯 TypeScript 程式碼時,如果您輸入錯誤的名稱、呼叫函式錯誤等,會收到警告。

考慮以下兩行程式碼

function func() {}
funcc();

對於第二行,我們收到此警告

Cannot find name 'funcc'. Did you mean 'func'?

另一個範例

const a = 0;
const b = true;
const result = a + b;

這次,最後一行的錯誤訊息是

Operator '+' cannot be applied to types 'number' and 'boolean'.

2.1.2 文件參數是良好的實務

許多人會為函式和方法的文件參數,無論如何

/**
 * @param {number} num - The number to convert to string
 * @returns {string} `num`, converted to string
 */
function toString(num) {
  return String(num);
}

透過 {number}{string} 指定類型並非必要,但英文說明也提到它們。

如果我們使用 TypeScript 的符號來記錄類型,我們可以獲得額外的好處,即檢查此資訊的一致性

function toString(num: number): string {
  return String(num);
}

2.1.3 TypeScript 提供額外的文件層

每當我將 JavaScript 程式碼轉移到 TypeScript 時,我都會注意到一個有趣的現象:為了找到函數或方法參數的適當類型,我必須檢查它在哪裡被呼叫。這表示靜態類型會提供給我本地的資訊,否則我必須在其他地方尋找這些資訊。

我確實發現了解 TypeScript 程式碼庫比 JavaScript 程式碼庫更容易:TypeScript 提供額外的文件層。

這個額外的文件在團隊合作時也有幫助,因為它更清楚地說明程式碼的使用方式,而且 TypeScript 經常會在我們做錯事時警告我們。

2.1.4 JavaScript 的類型定義改善自動完成

如果 JavaScript 程式碼有類型定義,那麼編輯器就可以使用它們來改善自動完成。

使用 TypeScript 語法的一個替代方案是透過 JSDoc 註解提供所有類型資訊,就像我們在本章節開始時所做的那樣。在這種情況下,TypeScript 也可以檢查程式碼的一致性並產生類型定義。如需更多資訊,請參閱 TypeScript 手冊中的〈類型檢查 JavaScript 檔案〉章節 https://typescript.dev.org.tw/docs/handbook/type-checking-javascript-files.html

2.1.5 TypeScript 讓重構更安全

重構是許多整合開發環境提供的自動化程式碼轉換。

重新命名方法是重構的一個範例。在純粹的 JavaScript 中執行此操作可能會很棘手,因為同一個名稱可能會指涉不同的方法。TypeScript 擁有更多關於方法和類型如何連接的資訊,這讓在 TypeScript 中重新命名方法更安全。

2.1.6 TypeScript 可以將新功能編譯到舊程式碼

TypeScript 傾向於快速支援 ECMAScript 第 4 階段功能(這些功能預計會包含在下一版 ECMAScript 中)。當我們編譯到 JavaScript 時,編譯器選項 --target 讓我們可以指定輸出相容的 ECMAScript 版本。然後,任何不相容的功能(稍後引入)都將編譯成等效的相容程式碼。

請注意,這種對舊版 ECMAScript 版本的支援不需要 TypeScript 或靜態類型:JavaScript 編譯器 Babel 也會執行此操作,但它將 JavaScript 編譯成 JavaScript。

2.2 使用 TypeScript 的缺點

2.3 TypeScript 迷思

2.3.1 TypeScript 程式碼很重量級

TypeScript 程式碼可以很重量級。但它不一定要這樣。例如,由於類型推論,我們通常可以省去一些類型註解

function selectionSort(arr: number[]) { // (A)
  for (let i=0; i<arr.length; i++) {
    const minIndex = findMinIndex(arr, i);
    [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // swap
  }
}

function findMinIndex(arr: number[], startIndex: number) { // (B)
  let minValue = arr[startIndex];
  let minIndex = startIndex;
  for (let i=startIndex+1; i < arr.length; i++) {
    const curValue = arr[i];
    if (curValue < minValue) {
      minValue = curValue;
      minIndex = i;
    }
  }
  return minIndex;
}

const arr = [4, 2, 6, 3, 1, 5];
selectionSort(arr);
assert.deepEqual(
  arr, [1, 2, 3, 4, 5, 6]);

這段 TypeScript 程式碼與 JavaScript 程式碼不同的唯一位置,是 A 行和 B 行。

TypeScript 有各種撰寫風格

2.3.2 TypeScript 是嘗試用 C# 或 Java 取代 JavaScript

最初,TypeScript 確實發明了一些自己的語言建構(例如列舉)。但自 ECMAScript 6 以來,它大多堅持成為 JavaScript 的嚴格超集。

我的印象是,TypeScript 團隊喜歡 JavaScript,不想用「更好的」東西取代它(這是 Dart 等的目標)。他們希望讓靜態類型化盡可能多的 JavaScript 程式碼成為可能。許多新的 TypeScript 功能都是由這種渴望推動的。