# Day19 【牙起來】 介面(Interface) - Typescript ## 介面 Interface 這是原本武器設定的寫法 將這幾把武器進行改寫,導入**介面(Interface)** ```typescript= let weapons = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11}, ]; ``` 改寫成 ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11}, ]; interface Weapon { name: string; atk: number; } ``` 使用Interface的話 必須完全符合所有的Property 讓所有被定義的`key`都有值,不能多也不能少 ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11, def: 1}, {name: '只是名稱長了一點但沒有任何攻擊力'}, ]; interface Weapon { name: string; atk: number; } ``` 若有多的屬性會觸發 `TS2322 Object literal may only specify known properties` 錯誤 若有少的屬性會觸發 `TS2741: Property is missing in type ` 錯誤 ![](https://i.imgur.com/XD2ONB9.png) ### 問號符號 - 可選的屬性 如果要讓屬性是**可以出現、可以不出現**的話 使用問號(Question Mark)`?` ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11, def: 1}, {name: '只是名稱長了一點但沒有任何攻擊力'}, ]; interface Weapon { name: string; atk?: number; def?: number; } ``` ### 可選(問號符號) 並不等於`undefined`、`null` 使用 `| undefined`、`| null` **並非可以不填寫此欄位** 而是仍要滿足此屬性,只是值可以帶入`undefined`或`null` ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11}, {name: '只是名稱長了一點但沒有任何攻擊力'}, ]; interface Weapon { name: string; atk: number | undefined | null; } ``` ![](https://i.imgur.com/PGmW3Cm.png) 修改過後 ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: undefined}, {name: '只是名稱長了一點但沒有任何攻擊力', atk: null}, ]; ``` ### 規定屬性只能填寫某幾個值 把type `string`拿掉之後 使用 `|` 後面接幾個字串,可規定此屬性的值只能是這幾項 ```typescript= let weapons: Array<Weapon> = [ {name: '小劍', atk: 5}, {name: '彎刀', atk: 7}, {name: '大魔劍', atk: 11} ]; interface Weapon { name: '小劍劍劍劍劍' | '彎刀' | '大魔劍'; atk: number; } ``` ![](https://i.imgur.com/h1KZjRP.png)