---
# System prepended metadata

title: 2. 介面 (Interface)

---

# 2. 介面 (Interface)

<style>
.blue {
  color: blue;
  font-weight: bold;
}
</style>

:::warning
interface  扮演了定義這些型別的角色，它可以明確約束你的程式碼。
:::

**例如定義一個座標的點：**
```typescript=
interface Point {
  x: number;
  y: number;
}

let position: Point = {
    x: 11,
    y: 25
};
```
**接著建立一個函式，它接受一個 Point 屬性的參數：**

```typescript=
function printPoint(p: Point): string {
  return `The x is ${p.x}, y is ${p.y}.`;
}
printPoint({ x: 1, y: 2 }) // The x is 1, y is 2.
```

**這時候傳入的參數如果不符合 Point，就會造成編譯錯誤。
若屬性是可選的，可以在屬性後面加上 ? 符號，例如：**

```typescript=
interface Point {
  x: number;
  y: number;
  z?: number;
}
```

</br>

#### **==任意屬性==:**

**使用 [propName: string] 定義了任意屬性取 string 型別的值。
需要注意的是，一旦定義了任意屬性，那麼確定屬性和可選屬性的型別都必須是它的型別的子集：**

```typescript=
interface Point {
  x: number;
  y: number;
  [propName: string]: any;
}

let position: Point = {
  x: 11,
  y: 25,
  z: 15
};

```

</br>



#### **==readonly屬性==:**

**一些對象屬性只能在對像剛剛創建的時候修改其值。你可以在屬性名前用 readonly來指定只讀屬性:**

```typescript=
interface Point {
    readonly x: number;
    readonly y: number;
}
```

**你可以通過賦值一個對象字面量來構造一個Point。賦值後， x和y再也不能被改變了。**

```typescript=
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error! 不可再變更
```

</br>

#### **==ReadonlyArray\<T>類型:==**

**它與Array\<T>相似，只是把所有可變方法去掉了，因此可以    確保數組創建後再也不能被修改：**

```typescript=
let temp: ReadonlyArray<number> = [1, 2, 3, 4];
let newData: number[];

newData = temp // error! 不可再變更
```

**可以看到就算把整個ReadonlyArray賦值到一個普通數組也是不可以的
但是你可以用類型斷言重寫：**

```typescript=
let temp: ReadonlyArray<number> = [1, 2, 3, 4];
let newData: number[];

newData = temp as number[] // 成功
```

