# Interface vs Any

### 為什麼要學型別系統？

當我們在開發 Angular 專案時，會處理很多資料，例如：

* 從 API 獲取的使用者資料
* 表單輸入的資料
* 傳遞給其他組件的資料

如果不好好管理這些資料的型別，可能會遇到：

* 打錯字不知道
* 使用了不存在的屬性
* 型別錯誤（例如：應該是數字卻給了字串）

### 認識 any 和 interface

#### any：最自由但最危險的型別

```typescript
// 使用 any 的例子
let data: any = {
  id: 1,
  name: "台北"
};

// 以下操作都不會在開發時報錯
data.namee;        // 打錯字了，但 TypeScript 不會提醒
data.id = "一";    // id 應該是數字，但給了字串也不會警告
data.nonexistent(); // 呼叫不存在的方法也不會提醒
```

#### interface：幫你檢查的好朋友

```typescript
// 定義一個介面
interface Location {
  id: number;      // 規定 id 一定要是數字
  name: string;    // 規定 name 一定要是字串
  code?: string;   // ? 表示這個屬性是可選的
}

// 使用介面
let location: Location = {
  id: 1,
  name: "台北"
  // code 可以不給，因為是可選的
};

// TypeScript 會幫你檢查錯誤
location.namee;     // ❌ 錯誤：namee 不存在
location.id = "一"; // ❌ 錯誤：不能把字串給數字型別
```

### 在 Angular 專案中的實際應用

#### 1. 建立專門的介面檔案

```typescript
// src/app/interfaces/location.interface.ts

// 定義位置的介面
export interface Location {
  locationId: number;    // 位置編號
  locationName: string;  // 位置名稱
  code: string;         // 位置代碼
  active?: boolean;     // 是否啟用（可選）
}
```

#### 2. 在組件中使用

```typescript
// search.component.ts
import { Location } from '../interfaces/location.interface';

export class SearchComponent {
  // 告訴 TypeScript 這是一個 Location 陣列的 Observable
  locations$: Observable<Location[]>;

  constructor() {
    // 當你使用這個變數時，TypeScript 會幫你檢查型別
    this.locations$.subscribe(locations => {
      locations.forEach(location => {
        console.log(location.locationName); // IDE 會自動提示可用的屬性
      });
    });
  }
}
```

### 為什麼要用 interface 而不是 any？

想像你在玩樂高：

* 使用 any 就像隨便組裝，可能會組出奇怪的形狀
* 使用 interface 就像照著說明書組裝，確保每個部件都在正確的位置

實際好處：

1. IDE 會提示可用的屬性
2. 打錯字會立即被發現
3. 型別錯誤會被及時發現
4. 團隊合作時，大家都知道資料的結構

### 實用小技巧

#### 1. 擴展介面

```typescript
// 基礎位置介面
interface BasicLocation {
  id: number;
  name: string;
}

// 擴展基礎介面，添加更多屬性
interface DetailedLocation extends BasicLocation {
  address: string;
  coordinates: {
    lat: number;
    lng: number;
  };
}
```

#### 2. 可選屬性的使用

```typescript
interface SearchOptions {
  keyword?: string;  // 搜尋關鍵字（可選）
  page?: number;     // 頁碼（可選）
  limit?: number;    // 每頁筆數（可選）
}
```

### 記住重點

1. 盡量避免使用 any
2. 為你的資料建立清楚的介面定義
3. 善用可選屬性（?）
4. 把介面檔案集中管理
