# Day20 【牙起來】 函式(function) - Typescript
> `:` 冒號(colon) 在`Typescript`中定義著**前面的變數或function的型別**
## 接收的參數型別
`function` 接收Input參數的小括號裡,`Parameter`必須帶有型別
ex: `x: number`
```typescript=
function test(x: number) {
console.log(x);
}
```
若沒給參數型別的話,會出現 `TS7006: Parameter implicitly has an 'any' type.` 錯誤

## 返回的參數型別
若要定義返回值`function return`的型別
則是加在`Parameter`右括號的後方
ex: `: void`、`: number`
```typescript=
function test1(x: number): void {
console.log(x);
}
function test2(x: number): number {
console.log(x);
return x;
}
```
---
### 接收物件參數
`function`接收一個武器物件,顯示此把武器的**攻擊力**
來玩看看會怎麼樣
用`getAtk()`來取得物件的攻擊力
```typescript=
let weapons: Array<Weapon> = [
{name: '小劍', atk: 5},
{name: '彎刀', atk: 7},
{name: '大魔劍', atk: 11},
];
interface Weapon {
name: string;
atk: number;
}
function getAtk(weapon: Weapon): number {
return weapon.atk;
}
let w = weapons[1];
console.log('您手上武器的攻擊力為: ' + getAtk(w));
```

現在加上三件**防具物件**
用`calDmg()`接收一把武器、一件裝備
計算這把武器可以對這件裝備造成多少傷害
```typescript=
let weapons: Array<Weapon> = [
{name: '小劍', atk: 5},
{name: '彎刀', atk: 7},
{name: '大魔劍', atk: 11},
];
let armors: Array<Armor> = [
{name: '大盾', def: 3},
{name: '五角盾', def: 6},
{name: '方金盾', def: 9},
]
interface Armor {
name: string;
def: number;
}
interface Weapon {
name: string;
atk: number;
}
function getAtk(weapon: Weapon): number {
return weapon.atk;
}
function calDmg(weapon: Weapon, armor: Armor): number {
return weapon.atk - armor.def;
}
let w = weapons[1];
let a = armors[1];
console.log('武器可以對裝備造成: ' + calDmg(w, a) + '傷害');
```

### 返回多種型別
定義好返回型別後,只能`return`該型別的值
這種情況下**一定要返回`number`**
不能說有的情況要返回`數字Number`、有的返回`字串String`、有的返回`null`
一定要統一口徑,符合函式的定義
```typescript=
function getAtk(weapon: Weapon): number {
if (weapon.atk < 1) {
// 這把武器似乎沒任何傷害,所以被扔進虛空辣
return;
}
if (weapon.atk > 9) {
return '這把武器很痛';
}
return weapon.atk;
}
```

若想返回多種型別,可以使用 `|` 來達成
返回型別改寫成這樣 `number | string | void`
```typescript=
function getAtk(weapon: Weapon): number | string | void {
if (weapon.atk < 1) {
// 這把武器似乎沒任何傷害,所以被扔進虛空辣
return;
}
if (weapon.atk > 9) {
return '這把武器很痛';
}
return weapon.atk;
}
```
### 接收物件陣列
如果今天要一次印出大量的**武器攻擊力**
`function` 需要接收多個武器
`Parameter` 為武器的陣列,而`return`值為數字陣列
```typescript=
function getAtks(weapons: Array<Weapon>): Array<number> {
let result: number[] = [];
weapons.forEach(
weapon => {
result.push(weapon.atk);
}
)
return result;
}
console.log('您手上武器的攻擊力為: ' + getAtks(weapons));
```

### 返回組合物件
設計一個`function`來**融合武器和裝備**
**組出融合的物件**,具有原本的武器攻擊力、裝備防禦力
連武器名稱也都串接保留
```typescript=
function mix(weapon: Weapon, armor: Armor): { name: string, atk?: number, def?: number } {
return {
name: weapon.name + armor.name,
atk: weapon.atk,
def: armor.def
};
}
let w = weapons[0];
let a = armors[1];
console.log('融合成的武器: ' + JSON.stringify(mix(w, a)));
```
