typescript-frontendlisted
Install: claude install-skill CloudyWing/ai-dotfiles
# 前端 TypeScript 規範
當偵測到前端 TypeScript 專案(`tsconfig.json` 中包含 Vue/React 相關設定)或使用者要求撰寫前端 TypeScript 程式碼時,請自動套用以下規範。
## 嚴格模式(Crucial)
### tsconfig.json 基本設定
```json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
}
}
```
- `strict: true` 為強制項。新專案不允許關閉。
- 遵循**專案既有設定**:若既有專案未啟用 strict,不強迫修改,但新檔案應以 strict 標準撰寫。
## 型別設計
### interface vs type
| 選擇 | 適用情境 |
| --- | --- |
| `interface` | 物件形狀定義(API 回應、Props、State)、可擴展的契約 |
| `type` | 聯合型別、交叉型別、Mapped Types、Utility Types 組合 |
```typescript
// ✅ interface:物件形狀
interface Order {
id: number;
customerName: string;
items: ReadonlyArray<OrderItem>;
note?: string;
}
// ✅ type:聯合型別
type OrderStatus = 'pending' | 'processing' | 'completed' | 'cancelled';
// ✅ type:複雜型別操作
type PartialOrder = Partial<Pick<Order, 'customerName' | 'note'>>;
```
- 同一專案中選定一種作為物件定義的預設,保持一致。
- **禁止**在 interface 和 type 之間反覆切換同一個型別定義。
### 禁止 any(Crucial)
```typescript
// ❌ 禁止
function process(data: any) { }
const result: any = fetchData();
// ✅ 替代方案
function process(data: unknown) {
if (isOrder(data)) {
// 窄化後使用
}
}
// ✅ 泛型
function process<T>(data: T): T { }
```
- `any` 完全繞過型別檢查,等同關閉 TypeScript。
- 需要表達「任意型別」時使用 `unknown`,強制呼叫端做型別窄化。
- 第三方套件缺少型別定義時,優先尋找 `@types/*` 套件;無法取得時,自行撰寫 `.d.ts` 宣告檔。
### 避免 as 斷言
```typescript
// ❌ 避免:型別斷言(跳過檢查)
const order = response.data a