# 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[] // 成功
```