[Node.js] 使用TypeScript編寫Node項目

8gw234 9年前發布 | 223K 次閱讀 Node.js 開發 TypeScript

原文地址:http://www.moye.me/2015/04/25/using_typescript/

 

入 TypeScript 坑有一段時間了,由衷的看好,所以決定在自留地絮叨一番。

是什么

TypeScript (以下簡稱TS)是巨硬推出的JavaScript轉譯語言,這意味著:

  1. 它需要編譯
  2. TS代碼會被編譯成JavaScript代碼
  3. </ol>

    TS的特點是提供 模塊、類、接口等一系列類型概念,協助開發者在編譯時就定位出一些傳統JavaScript項目的運行時錯誤,以實現巨硬所謂的”Robust components”(值得一提的是,TS是大名鼎鼎的 Anders Hejlsberg 主導的項目。

    為什么

    JavaScript 一般被視為一種動態類型、弱類型的語言,它擁有巨大的靈活性。 如下所示,類型的變化并不受約束:

    var x = 10;
    console.log(typeof x);  // result -> number
    x = 'hello';
    console.log(typeof x);  // result -> string

    那么TS引入的類型概念,又為哪般呢?來看一個示例:

    我有一個求和的函數

    function sum(x, y){
        return x + y;
    }

    但是你也可以這么用,JavaScript沒有意見,雖然結果不合理:

    sum(100, 'hello'); // result -> 100hello

    于是,我們用TS這樣的限定,保證以上調用是通不過編譯的(輸入都是number,返回也必須是number:

    function sum(x:number, y:number):number {
        return x + y;
    }

    因為我們堅信,對一個數字和一個字符串進行求和,不是一種理智的需求——且,sum這時求和的結果是可信的了。

    類示例

    在 Node 中,因為流和事件機制的強大,很多時候我們都會讓自己的類去繼承 events.EventEmitter,JS代碼看起來就像是這樣: 

    var events = require('events');
    var util = require('util');
    
    function MyClass(){
       events.EventEmitter.call(this);
    }
    
    util.inherits(MyClass, events.EventEmitter);

    如果你熟悉Node的一套理論,倒也還好,但其實用TS,能寫出更優雅的代碼:

    import events = require('events');
    import util = require('util');
    
    export class MyClass extends events.EventEmitter{
        constructor(){
            super();
        }
    }

    具體的語法規范這里不做解釋,有興趣的可以參考官方的 Specification

    這里想說的是,TS生成的JS代碼質量很高,上述片斷生成的代碼(閉包防污染也考慮到了:

    var __extends = this.__extends || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        function __() { this.constructor = d; }
        __.prototype = b.prototype;
        d.prototype = new __();
    };
    var events = require('events');
    var MyClass = (function (_super) {
        __extends(MyClass, _super);
        function MyClass() {
            _super.call(this);
        }
        return MyClass;
    })(events.EventEmitter);
    exports.MyClass = MyClass;

    在WebStrom中使用

    鄙人已退 Windows 開發保平安,也就只能說說WebStorm的使用問題了:

    首先,你得有一個TS編譯器 

    npm install -g typescript

    然后,在第一次新建.ts文件的時候,WebStorm會詢問是否為.ts文件添加watcher,這樣在文件有保存動作時,watcher會自動調用編譯器去編譯&生成——我的選項是“否”:稍微一點的項目都會使用Grunt/Gulp之類的自動化構建工具,編譯也就會納入為構建的一份子,那么以Grunt為例,編譯這事交給 grunt-ts 就再合理不過了。grunt-ts配置示例:

    ts: {
        default: {
            src: ['**/*.ts', '!node_modules/**/*.ts'],
            target: 'es5',
            outDir: '/repo/releases',
            options: {
                fast: "never",
                module: "commonjs",
                sourceMap: false,
                suppressImplicitAnyIndexErrors: true,
                preserveConstEnums: true
            }
        }
    }

    TS 在對待import require的庫時,有它自己的一套理論:它需要一個.d.ts文件來說明引用庫的Schema,比如引用underscore:

    import underscore = require('underscore');

    那么在項目中,需要存在一個 underscore.d.ts,其中聲明這么一句(完整示例請參考underscore.d.ts

    declare module "underscore" {
        export = _; //...
    }

    然后在引用的地方聲明一個.d.ts,引入:

    ///<reference path="underscore.d.ts"/>

    如此一來,方可正確通過編譯,亦能得到WebStorm的智能提示。當然,如果不爽這種麻煩的引用,也可以不用import,直接使用如下形式來跳過TS檢查:

    var underscore = require('underscore');

    一般而言,知名的第三方庫,都能在 DefinitelyTyped 項目中找到 .d.ts,而WebStorm亦提供了快捷引用方式:

    Preferences -> Languages & Frameworks -> Libraries -> Downloads… -> TypeScript community stubs,選你所需 Download & Install:

    參考

    1. TypeScript Handbook:online version

     

    更多文章請移步我的blog新地址: http://www.moye.me/  

 本文由用戶 8gw234 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!