# 認識 TypeScript
自從學習了 JavaScript 後就聽說了叫 TypeScript 的程式語言。
所以找了資料做一些整理來認識一下 TypeScript ,方便學習上更好吸收。
## TypeScript 是什麼 ?
Typescript 是一種由 Microsoft 開發的開源程式語言。是 JavaScript 的型別的超集,它可以編譯成純 JavaScript。編譯出來的 JavaScript 可以執行在任何瀏覽器上。TypeScript 編譯工具可以執行在任何伺服器和任何系統上。TypeScript 是開源的。
### 為什麼要學 TypeScript?
* 可以幫你提早發現錯誤
* 讓你的程式更穩定、更容易維護
* 在大型團隊開發時,大家用一致的型別規則會比較不容易踩雷
* 很多主流框架像 **React**、**Vue** 也都推薦使用 TypeScript
#### TypeScript 跟 JavaScript 的差異是什麼?
比較項目 | JavaScript | TypeScript
| -------- | -------- | -------- |
型別檢查 | 沒有型別限制,錯誤要等跑起來才知道 | 有靜態型別檢查,寫程式時就會提示錯誤
語法自由度 | 非常自由,彈性高,但也容易出錯 | 更嚴謹,讓大型專案更好管理
編譯執行 | 直接執行在瀏覽器或 Node.js 中 | 需先轉換(編譯)成 JavaScript 才能執行
IDE 支援 | 基本提示 | 更好的自動補全、型別提示
適用場景 | 小專案、快速開發 | 中大型專案、多人合作時更安全可靠
直接理解 TypeScript 是 JavaScript 的加強版,也因為超集 TypeScript 包含了 JavaScript 的所有語法和功能,所以
* 會寫 JavaScript,就幾乎已經會寫 TypeScript。
* JavaScript 的語法在 TypeScript 裡面都可以用。
* 可直接修改副檔名,`.js` 檔案可以直接重新命名為 `.ts` 即可
* TypeScript 編譯出來的 JavaScript 可以執行在任何瀏覽器上並轉為「所有」瀏覽器看的懂得東西包含(ES5 語法)。
還有主要特色是「加上了**型別系統**或稱**靜態型別系統**」(Type System)」。
## Type System 型別系統
Type System 就是幫變數、參數、函式等加上「資料型別」的規則,讓你可以清楚知道每個變數應該是什麼類型(例如是字串、數字、布林值等)。在寫錯型別時,編譯器會直接提醒你。
舉例來說
JavaScript 寫法:
```js
function greet(name) {
return "Hello, " + name;
}
greet(123); // 不會報錯,但結果是 "Hello, 123"
```
TypeScript 寫法:
```ts
function greet(name: string): string {
return "Hello, " + name;
}
greet(123); // 編譯時就會報錯:number 不是 string
```
這就是 TypeScript 的強大之處 — 在你寫錯時就馬上提醒,而不是等到網頁壞掉才發現。
### TypeScript 常見的型別(Primitive Types)
| 型別 | 說明 | 範例 |
| -------- | -------- | -------- |
string | 文字字串 | ``"Hello"``
number | 數字(包含整數與小數) | `123`, `3.14`
boolean | 布林值(真或假) | `true`, `false`
array | 陣列 | `string[]`, `number[]`
object | 物件(key-value 組合) | `{ name: "Amy", age: 18 }`
any | 可以是任何型別(不建議濫用) | `let data: any = 123`
unknown | 不確定型別(更安全的 any) | 需加判斷才能使用
null / undefined | 空值或未定義 | `let a: null = null`
void | 沒有回傳值(常用在函式) | `function sayHi(): void {}`
never | 永遠不會發生(例如拋錯的函式) | `function error(): never`
tuple | 固定長度且型別順序固定的陣列 | `let x: [string, number]`
enum | 列舉,讓值更有意義 | `enum Role { Admin, User }`
而型別系統又有著三種:
🔸 Type Annotation(型別註解)
意思是「手動指定變數或參數的型別」,這樣程式更清楚,也能避免錯誤。
範例:
```ts
let name: string = "Amy";
let age: number = 25;
let isOnline: boolean = true;
function greet(name: string): void {
console.log("Hi " + name);
}
```
這些 `: string`、`: number` 就是型別註解。
🔸 Type Inference(型別推論)
TypeScript 很聰明,會根據你給的值自動判斷型別,不用你每次都寫註解。
範例:
```ts
let msg = "Hello"; // TypeScript 自動推論 msg 是 string
let count = 10; // 推論為 number
```
不代表永遠不用寫型別,複雜結構還是建議加註解。
🔸 Type Assertion(型別斷言)
當你知道某個值的型別比 TypeScript 更清楚時,你可以強制告訴它是某個型別。
有兩種寫法:
```ts
let someValue: unknown = "Hello World";
// 方法1:尖括號寫法(舊式)
let strLength1: number = (<string>someValue).length;
// 方法2:as 語法(建議)
let strLength2: number = (someValue as string).length;
```
這告訴 TypeScript:「這個值我知道它是 string,請當成 string 處理。」
概念 | 說明
| -------- | -------- |
Type Annotation | 手動加型別
Type Inference | TypeScript 自己判斷型別
Type Assertion | 開發者強制告訴 TypeScript 它是什麼型別
### Class 跟 Interface
#### Class(類別)
➤ 用途:
用來建立「物件的模板」。可以用 class 來定義某種東西的屬性(變數)與方法(函式),就像在定義「一種東西」的樣子。
範例:
```ts
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hi, I'm ${this.name}, ${this.age} years old.`);
}
}
const tom = new Person('Tom', 25);
tom.sayHello();
```
➤ 重點:
`constructor` 是用來初始化物件的。
使用 new 建立物件實體(instance)。
可以加上修飾詞(public, private, protected)控制變數的使用範圍。
#### Interface(介面)
➤ 用途:
用來定義「型別的結構」,先訂好一個「規則」,哪些欄位是必要的、資料型別是什麼,但不會實作內容。常用來描述物件型別或規範 class 要有哪些內容。
範例:
```ts
interface PersonInfo {
name: string;
age: number;
}
function printInfo(p: PersonInfo) {
console.log(`${p.name} is ${p.age} years old.`);
}
const jane = { name: 'Jane', age: 30 };
printInfo(jane);
```
#### Interface 搭配 class:
```ts
interface CanFly {
fly(): void;
}
class Bird implements CanFly {
fly() {
console.log("Flapping wings...");
}
}
```
**注意事項**
* Interface 不能實作方法,只能定義結構。
* Class 裡的屬性必須符合 Interface 的規則(若用了 implements)。
* Class 裡的屬性與方法,一定要跟 interface 中定義的屬性與方法「一模一樣」才能通過編譯。
* Interface 可用來描述函式、陣列、物件結構,非常靈活。
* Interface 與 Type alias (type) 功能上有重疊,但 interface 比較適合擴充型別。
## 總結
學習過後,粗略的做了整理。
TypeScript 學起來不算完全輕鬆,尤其是剛接觸會被型別系統卡住與 Class 跟 Interface 的不熟悉。
但能提早發現拼錯屬性名、資料格式不對、傳錯參數這些問題,減少除錯時間。與主流框架 React、Vue 的推薦使用,就是好好學習 TypeScript 的理由了。
### 參考資料
* https://www.typescriptlang.org/
* https://willh.gitbook.io/typescript-tutorial/introduction/get-typescript
* https://vocus.cc/article/6466032cfd89780001cb03d1
* https://summer10920.github.io/2021/08-25/typescript/