TypeScript是由微軟開發的一種能用來編譯出JavaScript程式碼的程式語言,因其比JavaScript程式語言還多了一道編譯手續,能夠在編譯階段找出程式碼語法上的問題,而且也添加了型別檢查機制,讓程式更容易閱讀與偵錯,使得TypeScript更適合用來開發大型專案。TypeScript相容於JavaScript,白話一點來說就是JavaScript程式碼也可以通過TypeScript編譯器的編譯,而且還能夠實現JavaScript的版本轉換(例如ES6轉ES5)。



TypeScript官方網站:

在此先提醒一下,這個系列的文章並不會介紹程式開發的基本邏輯概念(如變數、迴圈等定義),因此可能比較不適合完全不懂程式語言的人參考,不過還是會從頭介紹TypeScript的語法和用法,讓不會JavaScript的開發者也能夠看得懂。

安裝與設定TypeScript開發環境

Node.js

為了要開發TypeScript程式,我們需要先設定好Node.js和npm環境,建議使用Node.js最新的LTS版本。

Node.js是JavaScript程式的執行環境,可以讓我們不必開啟網頁瀏覽器也可以執行JavaScript程式。而npm則是JavaScript的套件管理器,常會與Node.js一同被安裝。

Windows的使用者可以直接到Node.js官方網站下載到Node.js的安裝檔,而Linux作業系統或是macOS的使用者可以參考這篇文章來安裝指定版本的Node.js。

tsc

tsc是TypeScript程式的編譯器,能夠將TypeScript程式碼編譯為JavaScript程式。

執行以下npm指令,即可安裝tsc指令工具:

npm i -g typescript

Hello World

安裝與設定完TypeScript開發環境之後,就可以開始撰寫TypeScript程式啦!依照慣例,我們來寫寫看在學習程式語言時總會寫的第一支程式──「Hello World」。「Hello World」是一支非常簡單的小程式,執行這支程式之後,螢幕上就會印出Hello, world!這幾個字。

建立專案目錄

大部分的情況下,在開始撰寫TypeScript程式時,會使用npm來建立出Node.js專案,但由於「Hello World」是我們第一支的程式,我們傾向用最單純的方式完成它,所以在此先不使用npm

首先,建立一個用來存放TypeScript專案的目錄hello-world

建立TypeScript原始碼檔案

接著在專案目錄中建立一個純文字檔案,檔名取為index.ts。雖然這邊的檔案名稱使用index.ts之外的其它名稱也是可以,但我們在之後用Node.js專案來開發TypeScript程式時,主要會以index.ts作為程式進入點,所以還是先習慣一下這個名稱比較好。

接著使用文字編輯器開啟剛才建立的index.ts,並輸入以下程式碼:

console.log("Hello, world!");

存檔之後,先別急著用tsc編譯,我們可以直接使用Node.js提供的node指令,來嘗試執行它。指令如下:

node index.ts

typescript-introduction

從上圖中可以發現,node index.ts指令有被成功執行,而且也成功在螢幕上印出Hello, world!這幾個字了!

這是因為我們目前寫的程式,只是JavaScript的部份,所以Node.js可以直接執行。

hello函數

如果只在TypeScript寫JavaScript,那用TypeScript還有什麼意思?我們來將以上index.ts檔案的程式碼改成以下這樣吧!

function hello (target: string): void {                                                           
    console.log(`Hello, ${target}!`);
}
 
hello("world");

同樣地,在存檔之後先別急著用tsc編譯,我們可以直接使用Node.js提供的node指令,來嘗試執行它。指令如下:

node index.ts

typescript-introduction

這次的node index.ts指令就執行失敗了,因為Node.js並無法支援TypeScript自創的語法。所以我們要用tsc先編譯index.ts,指令如下:

tsc index.ts

typescript-introduction

以上指令會編譯index.ts檔案,並將結果輸出成index.js檔案。這個index.js檔案的內容如下:

function hello(target) {
    console.log("Hello, ".concat(target, "!"));
}
hello("world");

接著用Node.js執行index.js檔案試試。指令如下:

node index.js

typescript-introduction

如上圖,成功在螢幕上印出Hello, world!這幾個字了!

Hello World程式碼解析

我們來看以下剛才寫的(或是複製貼上的)TypeScript程式究竟是在做什麼。先看一下程式碼的第1行和第3行:

function hello (target: string): void {                                                           
    console.log(`Hello, ${target}!`);
}
 
hello("world");

這樣的結構定義了一個名叫hello的函數,並在名稱後面又使用了冒號:來連接了一個型別名稱,來限制這個函數的回傳值型別,void這個型別名稱表示沒有回傳值。如果函數名稱後面不加上冒號:的話,這個函數回傳的型別就會由tsc根據函數的實作方式來推論,這部份會在之後的章節詳細介紹。

第1行在左大括號{之前我們定義了這個函數的簽名(signature),小括號()內則是定義函數的參數,在此有一個名叫target的參數,且這個參數因為名稱後面又使用了冒號:來連接了一個型別名稱,所以這個target參數的型別必須要是string,也就是一個字串。換句話說,如果參數名稱後面不加上冒號:的話,這個參數就可以是任意型別(任意型別的型別名稱為any,剛才提到的void也是屬於any)。

接著來說明一下大括號{}的意義。這組緊接在函數簽名之後的大括號,定義了該函數的主體(body),也就是該函數被呼叫的時候要執行的敘述(statement)。

function hello (target: string): void {                                                           
    console.log(`Hello, ${target}!`);
}
 
hello("world");

程式第2行,使用了console這個JavaScript執行環境自帶的物件,可以用來存取主控台,其提供的log方法可以在主控台上印出從參數傳入的任意型別的值。藉由小數點.,我們可以存取某個值的屬性(property),console.log即表示要存取console這個物件下的log屬性,而log屬性所儲存的值是一個可以傳入任意數量的任意值作為參數的函數。

此處傳進log函數的第一個參數的值為一個字串,用`字元包了起來,並在其中以${}這樣的語法置入target參數的內容。這個`${}`語法是在ES6時被加入的,稱作「模板定數」(Template Literals),能讓我們直接在${}的大括號中填入JavaScript的表達式。至於分號,TypeScript的程式碼敘述的結尾分號寫不寫都可以,端看開發者的程式碼風格。

function hello (target: string): void {                                                           
    console.log(`Hello, ${target}!`);
}
 
hello("world");

程式第5行,呼叫了hello函數,並在第一個參數傳入world字串。此處的字串使用了JavaScript基本的字串語法,也就是用兩個單引號'或是雙引號"來將文字包裝起來,形成字串定數(literal)。順帶一提,JavaScript基本的字串語法無法直接換行,需要用\字元來跳脫才可以,但是「模板定數」是可以直接換行的。

如果我們像以下這樣將第5行的字串改為整數數值的話:

function hello (target: string): void {                                                           
    console.log(`Hello, ${target}!`);
}
 
hello(123);

則第5行會編譯失敗,因為TypeScript限制了target參數必須要是一個字串。

typescript-introduction

tsc編譯的目標(Target)

眼尖的人應該會發現,方才的「Hello World」程式index.ts檔案中的`Hello, ${target}!`,在被tsc編譯之後,會變成"Hello, ".concat(target, "!")。這是因為tsc會主動將新版的JavaScript語法轉為舊版的(ES3),以求最大的程式相容性。如果我們將`Hello, ${target}!`改成舊版JavaScript使用+運算子來連接字串的作法,也就是改成'Hello, ' + target + '!',然後再進行編譯,依然會得到'Hello, ' + target + '!'

當然,我們是可以控制tsc所輸出的JavaScript版本的。只要加上-t或是--target參數,再接上版本名稱就可以了。例如要編譯index.ts檔案並將其輸出成ES6的版本,指令如下:

tsc index.ts -t ES6

此時編譯出來的index.js檔案內容如下:

function hello(target) {
    console.log(`Hello, ${target}!`);
}              
hello("world");

有關於JavaScript版本的功能差異,可以參考這個網頁。有關於TypeScript支援輸出的JavaScript版本有哪些,之後的章節有用到時會再順便提及。

總結

在這一章中,我們設定好TypeScript的開發環境,學會了如何用TypeScript的編譯器,也就是tsc來將TypeScript程式碼編譯為JavaScript程式。

在下一章節中,我們將會實際寫一個簡單的小程式,來學習TypeScript程式語言的基本概念和語法!

下一章:用TypeScript寫個猜數字程式吧!