第229期 / November 4, 2016

研發新視界

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

TypeScript的介紹以及基本操作

作者/李沛承

[發表日期:2016/11/4]

為什麼要使用TypeScript

JavaScript寫得好好的為什麼要使用TypeScript呢?我認為可維護性對一個應用程式而言是相當重要的。許多人對JavaScript都有一個認知,就是JavaScript比較沒有辦法適用於大型的應用程式開發,大家都知道JavaScript寫出來的程式五花八門,同樣一個功能還可以用很多種方式寫出來,也知道JavaScript寫出來的程式不好維護而且只能在執行時期偵錯,不同人寫出來的JavaScript還很難理解,規模越大的JavaScript應用程式,偵錯的難度越高,所以啦,很多人就認為要寫好JavaScript的難度的確有點高,所以乾脆就少寫一點。

什麼是TypeScript

TypeScript是一個具有型別的JavaScript的超集合(SuperSet),也就是說原本的JavaScript本身就是涵蓋在TypeScript的語法之內,意思就是說原本的JavaScript語法在本身什麼都不修改的情況下他就是一個完整以及有效的TypeSctipt語法,並且100%相容。

可以把程式從JavaScript變成TypeScript並且在撰寫TypeScript的過程之中加上一些額外(TypeScript)的特性,最後再透過TypeScript的編譯器把TypeScript的語言編譯回ECMAScript3(ES3)相容的JavaScript,編譯後的JavaScript語法,相容於ECMAScript3所代表的就是它幾乎可相容於任何的瀏覽器上(包括連IE6以上版本都可以正常執行) 、任何主機或者任何的作業系統,並且它是開放原始碼!

TypeScript擁有的功能例如靜態型別檢查,由於JavaScript本身是個弱型別的程式語言,所以很難在開發時期發現一些程式的瑕疵,可以使用TypeScript的靜態型別檢察功能,透過TypeScript在編譯的過程之中,發現許多潛在的問題跟錯誤。另外像是類別、模組這樣的機制則可以幫助封裝程式的邏輯,這些封裝的特性是為了簡化JavaScript原本存在的物件特性,由於JavaScript本身是以原型為基礎的物件導向程式語言,而TypeScript試圖把它轉變為一個以類別為基礎的程式語言,而以類別為基礎的程式語言對一般的開發人員來說是比較熟悉的,而且語法也變得比較簡單,所以在封裝類別、設計界面甚至於設計一些繼承的特性時,語法上相對的會比用JavaScript來寫還簡單非常多。

JavaScript的特性

首先JavaScript是個動態型別的程式語言,以下來個範例:


《圖一》


這裡一開始用var宣告了一個test的變數,這個變數可以是任意型別,而且可以在執行的過程之中動態的去做切換,這就是動態型別的語言特性,這種無法在開發時期來宣告型別的特性通常又稱之為『弱型別』的程式語言。不過即便如此,JavaScript到底具不具備型別呢?事實上,JavaScript是有型別的,雖然使用var宣告變數可以容納任意物件,只是這些型別是在執行時期才擁有的,在開發時期是沒有辦法決定型別的。

JavaScript的型別分類:

一、基礎型別(Primitive Type)
● string
● number
● boolean
● undefined
● null

二、物件型別(Object Type)
● Object
● Array
● Function
● …

此外在執行時期當需要特別檢查型別的時候,自動型別轉換是一個大家普遍會遇到的問題,簡化頻繁檢查型別的動作,相對的缺點就是經常在型別自動轉化的過程之中發生錯誤,所以當自動型別轉換發生的時候,問題也就連帶的發生了,而且這些問題都是發生在執行時期,都得真的執行到那一行的時候錯誤才會發生,因此我們在用JavaScript開發網頁的時候偵錯是非常不容易的。

TypeScript的特性

TypeScript帶來的解決方案就是靜態型別檢查的功能,它可以把動態的型別特性轉變成靜態型別,透過一個TypeScript的編譯器來幫忙做型別的檢查,有了靜態型別檢查的功能就可以幫忙找出應用程式潛在發生的問題,尤其是打錯字以及型別不一致的問題。

TypeScript的型別分類:

基本型別(Basic Type)
● String
● Number
● Boolean
● Array
● Enum
● Any
● Void

這邊有一個特殊的型別是Any,代表任意型別的意思,也就是在TypeScript裡面依然保留了JavsScript原本動態型別的特性,所以還是可以把變數標示為Any的型別來代表這是一個動態型別的變數。

TypeScript主要特性:
一、靜態型別檢查(僅存在TypeScript編譯時期)

二、介面(interface)

三、類別(classes)

四、模組(modules)

五、函式

● Lambdas語法
● 函式多載

六、泛型

七、型別自動推導

八、宣告檔定義(*.d.ts)


先來一段純的JavaScript範例:


《圖二》JavaScript Code


這段程式碼,可以儲存為 sample.ts 這樣的檔案,然後透過 TypeScript 編譯器去編譯它,最後會產出一模一樣的 JavaScript 程式碼,這就顯示了它完全相容 JavaScript 語法,同時也證明可以繼續整合既有的 JavaScript libraries(如:jQuery, YUI 等),這都是其它 projects 比較少見的作法。所以只要是寫 JavaScript 的環境(瀏覽器、NodeJS)都可以運用 TypeScript。

TypeScript 到底對 JavaScript developers 有什麼好處呢?它最重要的任務就是在語言中加入了靜態型別(static typing)的語法,不僅讓開發人員利用這些語法撰寫更嚴謹的程式之外,也更容易讓其它工具來做程式碼分析,像是更容易最佳化程式碼或是程式碼編輯器中的語法提示(Intellisense)功能。

接下來使用TypeScript透過加入靜態型別來寫一樣的Code:


《圖三》TypeScript Code



《圖四》依照TypeScript Code產生出來的js檔


可以發現,編譯出來的js檔中的Code和之前的純JavaScript的Code是一模一樣的!接著若我們將原本程式中的obj變數在建構子的時後修改為:var obj = new BirthDay(2016,01,02);(故意製造錯誤的型別),那在編譯時,就會產生下面的錯誤訊息:


《圖五》使用TypeScript型別錯誤的錯誤訊息


如果是函式名不小心輸入錯了也是一樣有錯誤訊息,並且還可以做靜態型別檢查,不但省下很多Debug的閒工夫也提高了程式品質。


《圖六》使用TypeScript函式名錯誤的錯誤訊息


在這段程式碼中(圖七)可以看到 TypeScript 加入了interface的關鍵字,而且IBirthDay介面中的每一個成員都有宣告了它的type: string,並且在BirthDay的建構子中也加入了型別的描述,這樣一來就讓程式碼變得嚴謹得多,而透過 TypeScript 的編譯器編譯過後,便會產生這樣的程式碼(圖八):


《圖七》在TypeScript加入interface的關鍵字來使用



《圖八》依照TypeScript Code產生出來的js檔


結論

筆者覺得Typescript的概念真的很不錯,不但保留整體架構,而且就算有ㄧ些Code本來就是js檔的話也沒關係,它可以100%相容,讓javascript好的一面保留,導致不好開發的部分也提出了很不錯的解決方法,避免開發者犯ㄧ些打錯字以及型別不一致的錯誤,本來JavaScript只有在執行時期偵錯才能知道,而TypeScript在編譯時期就能夠知道。使用TypeScript還有一個非常大的優點就是工具支援,在Visual Studio下能還夠做自動編譯、自動型別檢查、命名重構以及還可以享受到到開發工具帶來的Intellisense功能,相信Typescript會成為一個前端工程師非常好的利器。

(本文轉載自RUN!PC)

參考連結

1.開發者之魂:快速瞭解 TypeScript 是什麼東西(Microsoft Developer網站

2.The Will Will Web

3.Alan Tsai 的隨手筆記:[Typescript] 如果Javascript是屬於組合語言(Assembly Language),那麼Typescript就是高級語言 - 概念

4.黑暗執行緒:Hello, TypeScript!

5.黑暗執行緒:NG筆記3-使用TypeScript