Typescript Overview
我第一個使用的前端框架是 Angular,自然也接觸了 Typescript,當時並不太能體會它的好處,只覺得增加了些學習門檻罷了。後來發現習慣以後,再也沒有辦法回到原本的 JS 了 ...,就算換了框架、使用 Node,都還是以 TS 為主,這篇文章來簡單介紹 TS 基本用法,回顧看看他到底為甚麼這麼令人著迷。
Typescript 是甚麼
TypeScript is a typed superset of Javascript that complies to plain JavaScript
這是官網上的簡介,TS 其實就是 JS 的超集,JS 有的所有語法在 TS 中都可以使用,也就是說現在找一個 JS 檔案改副檔名就可以直接編譯的過 (當然這樣做其實沒什麼意義) 。除了原本的語法外,TS 又加了其他的功能,最重要的也就是型別 (Types) 定義了。
由 JavaScript 開始,也以 JavaScript 結束
TS 使用 JS 中同樣的語法,你不用從頭來過,這也意味著所有過去以 JS 開發的函式庫都可以直接使用,只需要學習增加的功能就好。使用 TS 開發過後,必須要經過編譯回到原生 JS 後才可以使用,任何能跑 JS 的地方,都可以跑使用 TS 來開發的程式。
為甚麼我們需要「型別」?
為甚麼我們要在一個弱型別語言上加上型別定義呢,來看個簡單的例子吧!
JS 原生寫法
今天有個簡單的存錢小程式,呼叫 giveMeMore 後會印出加總過後的存款
let money = 10;
function giveMeMore(count) {
money = money + count;
console.log("Awesome, now I have $" + money);
}
giveMeMore(10); // Awesome, now I have $20
giveMeMore(10); // Awesome, now I have $30
看起來沒甚麼問題,直到今天有個人這樣用了你的函式:
giveMeMore("10"); // Awesome, now I have $3010
JS 會先把 money 轉換型別,然後把字串 10 附加在後面,所以得到的結果會是 3010
,此時就算使用正確的型別輸入也於事無補了 ...
giveMeMore(10); // Awesome, now I have $301010
加入型別檢查
當然,這是個簡單的問題,非常好預防,只需要在 function 執行前做檢查就好了
function giveMeMore(count) {
if (typeof count !== "number") {
throw new Error("Go away...");
}
money = money + count;
console.log("Awesome, now I have $" + money);
}
檢查的部分通常也需要個測試來涵蓋她
it("should throw except when input type is not number", function () {
// some assert
});
使用 Typescript
有了型別以後,編譯器會自動擋下不符合要求的程式,不需要再額外測試。
TS 會在編譯階段自動作型別檢查,而不是到執行階段才處理,這可以提升一些效能。
JS 的弱型別特性給了我們很大的彈性 (相對於強行別語言,需要先思考架構 ),使我們可以快速開發,在小型網頁上使用使合情合理的。但隨著各種框架出現,JS 被應用在更大型、需要長期維護的專案,這可能就會增加維護的難度,TS 在型別定義上做了很大的改善,縱使需要寫更多的程式、需要經過編譯,依然是個值得考慮的選擇。
Getting Started
Compile
TS 的副檔名會改為 .ts
,我們必須將它轉回 .js 檔案
TS 編譯時需要有設定檔 tsconfig.json ,請參考官網來設定。
使用 TSC
官方預設的編譯器,在沒有使用 Webpack 的時候會這麼做 (像是 Node JS 環境 )
安裝
npm install -g typescript
編譯
tsc helloworld.ts
使用 Loader
通常前端開發會使用 Webpack ,這時候就可以使用 ts-loader 來轉換檔案
module: {
rules: [
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
{ test: /\.tsx?$/, loader: "ts-loader" },
];
}
基本型別
現有的 JS 檔案把檔名都改為 TS 後,應該就可編譯過了 (JS 可以寫的東西,在 TS 中一定沒問題),我們先從 TS 中的基本型別開始加入
Any
所有的型別,和不定型別是一樣的意思,此時 TS 不會檢查 -> 除了這個,否則型別定了之後是改不了的
let a: any;
a = "1";
a = 1;
Boolean / String / Number
let a: boolean;
a = true; // ok
a = 1; // error
let b: number;
b = 3; // ok
b = 3.33; // ok
Array
必須要先說好,陣列裡面會有啥
let a: number[];
a = [1, 2, 3, 4]; // ok
a = [1, "2"]; // error
let b: any[];
b = [1, "2"]; // ok