總結:TypeScript 知識地圖
恭喜你完成了 TypeScript 完整指南!本篇將整理所有重點,提供速查表和進階學習資源。
一、 類型系統總覽
1.1 類型分類
1.2 類型關係
| 類型 | 是所有類型的 | 說明 |
|---|---|---|
unknown | 父類型 | Top Type |
never | 子類型 | Bottom Type |
any | 父+子類型 | 雙向相容 |
二、 語法速查表
2.1 基礎語法
typescript
// 類型標註
let name: string = 'John';
let age: number = 30;
let active: boolean = true;
// 陣列
let numbers: number[] = [1, 2, 3];
let strings: Array<string> = ['a', 'b'];
// 元組
let tuple: [string, number] = ['John', 30];
// 物件
let user: { name: string; age: number } = { name: 'John', age: 30 };
// 函式
function greet(name: string): string {
return `Hello, ${name}`;
}
// 箭頭函式
const add = (a: number, b: number): number => a + b;2.2 interface vs type
typescript
// interface - 物件定義
interface User {
name: string;
age: number;
}
// interface - 擴展
interface Admin extends User {
role: string;
}
// type - 類型別名
type Status = 'pending' | 'success' | 'error';
// type - 組合
type UserOrAdmin = User | Admin;
type UserAndAdmin = User & Admin;2.3 泛型
typescript
// 函式泛型
function identity<T>(value: T): T {
return value;
}
// 介面泛型
interface ApiResponse<T> {
data: T;
success: boolean;
}
// 約束
function getLength<T extends { length: number }>(value: T): number {
return value.length;
}
// 預設值
type Container<T = string> = { value: T };2.4 條件類型
typescript
// 條件類型
type IsString<T> = T extends string ? true : false;
// infer
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
// 分發條件
type ToArray<T> = T extends any ? T[] : never;
// ToArray<string | number> = string[] | number[]2.5 映射類型
typescript
// 基本映射
type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Partial<T> = { [K in keyof T]?: T[K] };
// 鍵重映射
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};三、 內建工具類型速查
3.1 物件操作
| 工具類型 | 用途 | 範例 |
|---|---|---|
Partial<T> | 全部可選 | Partial<User> |
Required<T> | 全部必填 | Required<Config> |
Readonly<T> | 全部唯讀 | Readonly<User> |
Pick<T, K> | 選取屬性 | Pick<User, 'id' | 'name'> |
Omit<T, K> | 排除屬性 | Omit<User, 'password'> |
Record<K, V> | 建立物件 | Record<string, number> |
3.2 聯合操作
| 工具類型 | 用途 | 範例 |
|---|---|---|
Exclude<T, U> | 排除成員 | Exclude<'a' | 'b', 'a'> |
Extract<T, U> | 提取成員 | Extract<'a' | 'b', 'a'> |
NonNullable<T> | 排除 null/undefined | NonNullable<string | null> |
3.3 函式操作
| 工具類型 | 用途 | 範例 |
|---|---|---|
Parameters<T> | 取得參數類型 | Parameters<typeof fn> |
ReturnType<T> | 取得回傳類型 | ReturnType<typeof fn> |
ConstructorParameters<T> | 建構函式參數 | ConstructorParameters<typeof Class> |
InstanceType<T> | 實例類型 | InstanceType<typeof Class> |
3.4 字串操作
| 工具類型 | 用途 | 範例 |
|---|---|---|
Uppercase<S> | 轉大寫 | Uppercase<'hello'> |
Lowercase<S> | 轉小寫 | Lowercase<'HELLO'> |
Capitalize<S> | 首字母大寫 | Capitalize<'hello'> |
Uncapitalize<S> | 首字母小寫 | Uncapitalize<'Hello'> |
四、 Vue3 + TypeScript 速查
4.1 Composition API
typescript
// ref
const count = ref(0); // Ref<number>
const user = ref<User | null>(null); // Ref<User | null>
// reactive
const state = reactive<State>({ count: 0 });
// computed
const double = computed(() => count.value * 2);
// watch
watch(count, (newVal, oldVal) => {});4.2 元件類型
typescript
// Props
interface Props {
title: string;
count?: number;
}
const props = defineProps<Props>();
// Emit
const emit = defineEmits<{
update: [id: number];
delete: [id: number];
}>();
// Expose
defineExpose<{
open: () => void;
close: () => void;
}>({ open, close });4.3 路由與狀態
typescript
// Vue Router
const route = useRoute();
const router = useRouter();
// Pinia
const store = useUserStore();
const { count } = storeToRefs(store);五、 Node.js + TypeScript 速查
5.1 Express 類型
typescript
// Request 類型
app.post(
'/users',
(
req: Request<Params, ResBody, ReqBody, ReqQuery>,
res: Response<ResBody>
) => {}
);
// 擴展 Request
declare global {
namespace Express {
interface Request {
user?: User;
}
}
}5.2 Zod 驗證
typescript
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
type User = z.infer<typeof userSchema>;
const result = userSchema.safeParse(data);六、 tsconfig.json 關鍵選項
| 選項 | 建議值 | 說明 |
|---|---|---|
strict | true | 啟用嚴格模式 |
noImplicitAny | true | 禁止隱式 any |
strictNullChecks | true | 嚴格 null 檢查 |
esModuleInterop | true | ES 模組相容 |
skipLibCheck | true | 跳過 .d.ts 檢查 |
target | ES2022 | 編譯目標 |
module | NodeNext | 模組系統 |
七、 學習路徑建議
7.1 初學者
基礎類型 → 函式類型 → interface/type → 泛型基礎7.2 中階
類型守衛 → 條件類型 → 映射類型 → 內建工具類型7.3 進階
類型體操 → 自訂工具類型 → 框架類型整合八、 常見錯誤與解決
8.1 類型錯誤
| 錯誤 | 原因 | 解決 |
|---|---|---|
Object is possibly undefined | null 檢查 | 使用 ?. 或 ! |
Argument of type X is not assignable to Y | 類型不符 | 檢查類型定義 |
Property does not exist | 屬性不存在 | 添加屬性或使用斷言 |
Cannot find module | 模組找不到 | 安裝 @types/xxx |
8.2 最佳實踐
- 避免使用
any,用unknown替代 - 優先使用類型推論
- 複雜類型拆分成小單位
- 使用區分聯合處理狀態
九、 推薦資源
9.1 官方資源
9.2 學習資源
- Type Challenge - 類型練習
- TypeScript Deep Dive - 深入書籍
- Total TypeScript - 進階課程
9.3 工具
總結
TypeScript 是一個強大的工具,它:
- 在編譯時期發現錯誤
- 提供優秀的 IDE 支援
- 讓重構更安全
- 作為程式碼文件
> **持續學習**:
- 閱讀優秀的開源專案
- 嘗試 Type Challenge
- 實踐中學習
進階挑戰
- 完成 Type Challenge 的 Easy 題目
- 為一個現有 JavaScript 專案加上 TypeScript
- 建立一個類型安全的 Vue3 + Pinia + Vue Router 專案
系列回顧
恭喜你完成了這個系列!你已經學會了:
- TypeScript 基礎類型系統
- 進階類型操作
- 泛型與條件類型
- Vue3 + TypeScript 整合
- Node.js/Express 類型安全
- 類型體操與自訂工具類型
繼續練習,讓 TypeScript 成為你的強力工具!