JavaScript >> Javascript 文檔 >  >> Tags >> TypeScript

關於 TypeScript 的思考

本週早些時候,微軟發布了 TypeScript 1 ,一種用於“應用程序規模的 JavaScript”的新的編譯為 JavaScript 的語言。我最初的反應是困惑:

似乎幾乎每週都有一種新語言試圖在網絡上取代 JavaScript。 Google 在推出 Dart 2 時受到冷遇 ,它自己的想法是修復所有 JavaScript 的感知缺陷。 CoffeeScript 3 仍然是這些選項中最突出的,經常在網上煽動聖戰。而現在微軟正大步向前,我不禁想知道為什麼。

我的偏見

在專門討論 TypeScript 之前,我想解釋一下我的個人偏見,以便您可以在適當的上下文中理解我的其餘評論。 Web 開發行業存在一個非常現實的問題,即嚴重缺乏優秀的 JavaScript 開發人員。我無法告訴你有多少公司與我聯繫,試圖找到高於平均水平的 JavaScript 人才來開發他們的應用程序。是的,現在的 JavaScript 開發人員比 10 年前要多得多,但需求的增長速度遠遠超過了供應的增長速度。根本沒有足夠的人來填補所有可用的 JavaScript 工作。這是個問題。

有些人會爭辯說,高需求和低供應使優秀的 JavaScript 開發人員處於一個非常棒的位置,我們永遠不應該改變這一點。畢竟,這就是為什麼我們可以要求我們的薪水。從個人經濟角度,我同意。從想要改進網絡的角度來看,我不同意。是的,我希望能夠通過自己的工作過上好日子,但我也希望整個網絡繼續發展並變得更好,而這只有在我們有更多有能力的開發人員進入勞動力市場時才會發生。

我認為編譯為 JavaScript 的語言是實現這一目標的障礙。我們應該說服更多人學習 JavaScript,而不是給他們更多不寫 JavaScript 的選擇。我經常想知道,如果所有花費時間、精力、人員和金錢來開發這些替代方案的團隊和公司都將這些資源用於改進和教授 JavaScript,會發生什麼。

需要明確的是,我並不是說 JavaScript 是一種完美的語言並且沒有缺點。我用過的每一種語言都有糟糕的部分和很棒的部分,JavaScript 也不例外。我確實相信 JavaScript 必鬚髮展,這必然會引入更多糟糕的部分以及更多很棒的部分。我只是希望我們都將精力放在同一個領域,而不是分散在不同的項目中。

什麼是 TypeScript?

本週我花了很多時間查看 TypeScript,閱讀文檔,並觀看網站上的視頻。然後我被 Rey Bango 邀請與 TypeScript 團隊的幾位成員會面,回答我自己的問題。有了這些背景,我覺得我對 TypeScript 是什麼和不是什麼有了一個很好的了解。

TypeScript 首先是 JavaScript 的超集。這意味著您可以在 TypeScript 中編寫常規 JavaScript,並且它是完全有效的。 TypeScript 在 JavaScript 之上添加了其他功能,然後由 TypeScript 編譯器轉換為 ECMAScript 5 兼容代碼。這是一種有趣的方法,與其他編譯成 JavaScript 的語言完全不同。 TypeScript 不是用新的語法規則創建一種全新的語言,而是從 JavaScript 開始,並添加了非常適合語法的附加功能。

最基本的,TypeScript 允許您使用類型信息來註釋變量、函數參數和函數。與使用普通 JavaScript 相比,這些附加信息允許工具提供更好的自動完成和錯誤檢查。語法是從原始的 JavaScript 2/ECMAScript 4 提案 4 借來的 這也是作為 ActionScript 3 實現的:

var myName: string = "Nicholas";

function add(num1: number, num2: number): number {
    return num1 + num2;
}

function capitalize(name: string): string {
    return name.toUpperCase();
}

如果您曾經使用過 Pascal 或 Delphi,冒號語法可能看起來很熟悉,它們都使用相同的語法來指示類型。 JavaScript 中的字符串、數字和布爾值在 TypeScript 中表示為 string , number , 和 bool (注:全部小寫)。這些註解幫助 TypeScript 編譯器判斷你是否使用了正確的值。例如,以下會導致警告:

// warning: add() was defined to accept numbers
var result = add("a", "b");

add() 被定義為接受數字,此代碼會導致 TypeScript 編譯器發出警告。

TypeScript 也很聰明,可以在有賦值時推斷類型。例如,這些聲明中的每一個都會自動分配一個類型:

var count = 10;           // assume ": number"
var name = "Nicholas";    // assume ": string"
var found = false;        // assume ": bool"

這意味著要從 TypeScript 中獲得一些好處,您不必在任何地方都添加類型註釋。你可以選擇不添加類型註解,讓編譯器嘗試解決問題,也可以添加一些類型註解來幫助解決。

也許這些註釋中最酷的部分是正確註釋回調函數的能力。假設您想對數組中的每個項目運行一個函數,類似於 Array.prototype.forEach() .使用 JavaScript,您可以定義如下內容:

function doStuffOnItems(array, callback) {
    var i = 0,
        len = array.length;

    while (i < len) {
        callback(array[i], i, array);
        i++;
    }
}</code>

回調函數接受三個參數,一個值、一個索引和數組本身。除了閱讀代碼之外,沒有辦法知道這一點。在 TypeScript 中,您可以更具體地註釋函數參數:

function doStuffOnItems(array: string[], 
        callback: (value: string, i: number, array: string[]) => {}) {
    var i = 0,
        len = array.length;

    while (i < len) {
        callback(array[i], i, array);
        i++;
    }
}</code>

此代碼為 doStuffOnItems() 的兩個參數添加註釋 .第一個參數定義為字符串數組,第二個參數定義為接受三個參數的函數。請注意,定義函數類型的格式是 ECMAScript 6 粗箭頭函數語法。 5 有了這些,編譯器就可以在代碼執行之前檢查函數是否與簽名匹配。

類型註釋確實是 TypeScript 的核心,也是它的設計目的。通過擁有這些附加信息,編輯器不僅可以在執行代碼之前對其進行類型檢查,還可以在您編碼時提供更好的自動完成支持。 TypeScript 已經有適用於 Visual Studio、Vim、Sublime Text 2 和 Emacs 的插件, 6 所以有很多選擇可以嘗試。

附加功能

雖然 TypeScript 的主要目的是為 JavaScript 提供一些靜態類型的外觀,但它並不止於此。 TypeScript 還支持 ECMAScript 6 類 7 和模塊 8 (正如它們當前定義的那樣)。這意味著你可以這樣寫:

class Rectangle {
    constructor(length: number, width: number) {
        this.length = length;
        this.width = width;
    }

    area() {
        return this.length * this.width;
    }
}

TypeScript 將其轉換為:

var Rectangle = (function () {
    function Rectangle(length, width) {
        this.length = length;
        this.width = width;
    }
    Rectangle.prototype.area = function () {
        return this.length * this.width;
    };
    return Rectangle;
})();

請注意,構造函數已正確創建,並且 one 方法已正確放置在原型上。

除了模塊和類之外,TypeScript 還引入了定義接口的能力。接口在 ECMAScript 6 中根本沒有定義,但在類型檢查方面對 TypeScript 很有幫助。由於 JavaScript 代碼往往定義了大量的對象字面量,因此接口提供了一種簡單的方法來驗證是否使用了正確類型的對象。例如:

interface Point {
    x: number;
    y: number;
}

function getDistance(pointA: Point, pointB: Point) {
    return Math.sqrt( 
               Math.pow(pointB.x - pointA.x, 2) +
               Math.pow(pointB.y - pointA.y, 2)
           );
}

var result = getDistance({ x: -2, y: -3}, { x: -4, y: 4})

在這段代碼中,有一個名為 Point 的接口 有兩個屬性 xy . getDistance() 函數接受兩個點併計算它們之間的距離。這兩個參數可以是恰好包含 x 的這兩個屬性的任何對象 和 y ,這意味著我可以傳入對象字面量,TypeScript 將檢查以確保它們包含正確的屬性。

接口和類都輸入到類型系統中以提供更好的錯誤檢查。模塊只是將相關功能組合在一起的方法。

我喜歡什麼

我使用 TypeScript 的次數越多,我就越能找到我真正喜歡的部分。首先,我喜歡你可以在 TypeScript 中編寫常規的 JavaScript。微軟並沒有試圖創造一種全新的語言,他們試圖以一種有用的方式來增強 JavaScript。我很感激。我也喜歡將代碼編譯成真正有意義的常規 JavaScript。調試 TypeScript 生成的代碼並不是那麼困難,因為它使用熟悉的模式。

最讓我印象深刻的是 TypeScript 沒有做的事情。它不會將類型檢查輸出到您的 JavaScript 代碼中。所有這些類型註釋和錯誤檢查都設計為僅在您開發時使用。除非您使用 JavaScript 代碼手動進行,否則最終代碼不會進行任何類型檢查。類和模塊被轉換成常規的 JavaScript,而接口則完全消失。接口代碼從未出現在最終的 JavaScript 中,因為它們純粹在開發期間用於類型檢查和自動完成目的。

TypeScript 的編輯器集成非常好。您所要做的就是添加一些註釋,突然間編輯器開始顯示潛在的錯誤和建議。為回調函數顯式定義期望的能力尤其令人印象深刻,因為這是我經常看到與將錯誤值傳遞給函數相關的許多問題的一個領域。

我也喜歡微軟開源的 TypeScript。他們似乎致力於公開開發此功能並圍繞 TypeScript 開發社區。他們是否會堅持到底並真正作為一個開源項目運作還有待觀察,但他們至少已經採取了措施來實現這種可能性。

我不喜歡的東西

雖然我對 Microsoft 決定使用 ECMAScript 6 類表示讚賞,但我擔心這會使該語言陷入困境。根據與我交談過的 TypeScript 團隊成員的說法,他們絕對計劃與模塊和類的 ECMAScript 6 語法保持同步。從理論上講,這是一種很好的方法,因為它鼓勵人們學習將來有用的技能。實際上,這是一個困難的提議,因為 ECMAScript 6 還沒有完成,並且不能保證在規範完成之前語法不會再次改變。這讓 TypeScript 團隊處於一個非常困難的境地:繼續更新語法以反映 ECMAScript 6 的當前現實或落後(可能分叉?)以保持他們的開發環境穩定。

類型註釋也是如此。雖然之前有大量工作表明冒號語法可以在 JavaScript 中使用,但不能保證它會被添加到語言中。這意味著 TypeScript 當前所做的可能最終與 ECMAScript 最終所做的不一致。這也將導致決定走哪條路。

TypeScript 團隊希望社區能夠圍繞語言和工具發展,以幫助告知他們在出現此類決策時該往哪個方向發展。這也是一把雙刃劍。如果他們成功地圍繞 TypeScript 創建了一個大型社區,由於升級現有代碼的高維護成本,社區很可能會決定放棄 ECMAScript 標準而不是堅持使用它。

而且我真的不喜歡有一個名為 bool 的原始類型 .我已經告訴他們​​我希望看到將其更改為 boolean 以便它映射回從 typeof 返回的值 ,以及 stringnumber .

你應該使用它嗎?

我認為 TypeScript 有很多希望,但請記住一件事:當前的產品是早期的 alpha 版本。從網站上看可能不太像,很精緻,或者編輯器插件,或者版本號被列為 0.8.0 的事實,但我確實與 TypeScript 團隊確認他們認為這是一個非常早期的實驗性版本,讓開發人員預覽即將發生的事情。這意味著在 TypeScript 穩定之前(可能隨著 ECMAScript 6 穩定),明年情況可能會發生重大變化。

那麼現在值得使用嗎?我只會說實驗性的並向 TypeScript 團隊提供反饋。如果您選擇在日常工作中使用 TypeScript,則風險自負,我強烈建議您堅持使用類型註釋和接口,因為它們已從編譯代碼中刪除並且不太可能更改,因為它們沒有直接關係到 ECMAScript 6。我會避免使用 ECMAScript 5 目前不支持的類、模塊和其他任何東西。

結論

TypeScript 提供了與其他編譯為 JavaScript 的語言非常不同的東西,因為它從 JavaScript 開始,並在其之上添加了附加功能。我很高興常規 JavaScript 可以用 TypeScript 編寫,並且仍然受益於 TypeScript 編譯器提供的一些類型檢查。這意味著編寫 TypeScript 實際上可以幫助人們學習 JavaScript,這讓我很高興。毫無疑問,這些類型註釋在與編輯器集成時可以創造更好的開發體驗。一旦 ECMAScript 6 最終確定,我可以看到 TypeScript 的巨大用途,允許開發人員編寫 ECMAScript 6 代碼,這些代碼仍然可以在原生不支持它的瀏覽器中工作。我們距離那個時候還有很長的路要走,但與此同時,TypeScript 值得關注。

參考

  1. TypeScript (typescriptlang.org)
  2. 飛鏢 (dartlang.org)
  3. CoffeeScript (coffeescript.org)
  4. 提議的 ECMAScript 第 4 版 - 語言概述 (ECMA)
  5. ECMAScript 6 箭頭函數語法 (ECMA)
  6. Sublime Text、Vi、Emacs:已啟用 TypeScript! (MSDN)
  7. ECMAScript 6 最大最小類 (ECMA)
  8. ECMAScript 6 模塊 (ECMA)

Tutorial JavaScript 教程
  1. 從 JavaScript 到 Python——學習一門新語言 Pt.2

  2. React JS 如何/從哪裡開始? :學習 React 的最佳方式

  3. 在 React Native 中創建和自定義單選按鈕

  4. 在無限滾動組件上改進觸摸事件

  5. 將 Canvas 元素下載到圖像

  6. CSS Quickies:CSS 變量 - 或者如何輕鬆創建🌞white/🌑dark 主題

  7. 您如何真正開始? (免費工作如何......工作?)

  1. Waldo:在 1 KB 內搜索 JavaScript 對像模型

  2. 管理多個 NodeJS 版本

  3. Telescope項目第二次PR

  4. 反應和解

  5. 在 node.js 中多次發送 http 請求

  6. 使用 Fokus 進行模態樣式文本選擇

  7. 嘗試將數據庫(firestore)中的字符串值與文本字段中輸入的字符串進行比較。我正在使用 vue 框架

  1. 使用 XState 構建用於表單處理的通用狀態機

  2. [React] 渲染動態內容列表

  3. 學習愛正則表達式

  4. 如何在 Stripe Checkout 會話中獲取購物車項目