【TypeScript】TypeScriptの型2

###TypeScriptの型のまとめ
* Union型 
* Literal型
* Alias型/Custom型
* unknown型
* never型 

ここで取り上げていない[TypeScriptの基本的な型] (https://qiita.com/suema0331/items/a0920ff50c0ffc100290)については、リンク先を参考にしてください(^o^)

#TypeScriptの型
| 型 | 説明 |
|:-:|:-:|
| Union型  |  複数の型を指定できる |
| Literal型  | 値そのものを厳密に指定する  |
| Alias型/Custom型  |  型の名前をつける |
| unknown型  | 最終的にどの型になるのかわからない事を表す  |
| never型  | 絶対に値を返さない時に使う |
	

##Union型
* `|`で複数の型を指定できます


```ts
//union型を使わない場合
function combine(input1: number, input2: number) {
  const result = input1 + input2;
    return result;
}

const combineAges = combine(30,26);
console.log(combineAges);

// number以外を引数に渡したので、errになる
const combineNames = combine('Max','Alice');
console.log(combineNames);  
```

* ここで、union型で複数の型を指定できるように修正します

```ts

function combine(input1: number | string, input2: number | string) { //numberか、stringを受け取れる

 let result;

    if (typeof input1 === 'number' && typeof  input2 === 'number' ){   //runtime上でデータ型を確認する必要
    result = input1 + input2;
    } else {
    result = input1.toString() + input2.toString();  //明示的に文字列に変換して結合
    }

  return result;
}

```

##Literal型
* 値そのものを厳密に指定する型です

```ts
//ex:文字列か数値を受け取って出力する関数

const number2 = 2.8; 

function combine(
input1: number | string, 
input2: number | string, 
resultConversion: string  //returnで返す型を指定できる
) {
    let result;
    if (typeof input1 === 'number' && typeof  input2 === 'number'  ) ||  resultConversion === 'as-number' {  
      result = + input1 +  + input2; //数値として結合
     } else {
      result = input1.toString() + input2.toString();  
   }
   return result;
}

const combineAges = combine(30,26 , 'as-number'); 

const combineAges = combine( '30', '26' , 'as-number'); //引数は文字列であるが、結果は数値で受け取りたい

const combineNames = combine('Max','Alice' ,'as-text'); 
```

* 🌟Literal 型を使えば、resultConversion: に特定の string しか入れられないように指定できます

```ts
function combine(
   input1: number | string, 
   input2: number | string, 
   resultConversion:  'as-number' | 'as-text'   //returnで返す型を指定できる
) {
//...略
}
```

* こうすると、関数内で、指定したstring以外を受け取れず、
`resultConversion === 'as-nekoooooo' `など指定したstring以外の場合、引数として渡せないようになります~(^o^)✨

##Alias型/Custom型
* 🌟型の定義を再利用し、型の名前をつけることで、型の意味を明文化できます
    * 必ず同じ型を指定できるメリットがあります
    * なんども同じことを書く場合に便利です

```ts
type  Combination = number | string; 
type  CombinationDescription = 'as-number' | 'as-text' ; 

//Alias型を使わない関数

function combine(
input1: number | string, 
input2: number | string, 
resultConversion:  'as-number' | 'as-text'   //returnで返す型を指定できる
) {
//...略
}

//Alias型を使った関数

function combine(
input1: Combination , 
input2: Combination , 
resultConversion:  CombinationDescription ,  //returnで返す型を指定できる
) {
//...略
}
```

* Object 型に対しても型エイリアスを使えます

```ts
type User = { name: string; age: number };
 
function greet(user: User) {
  console.log('Hello! I am ' + user.name);
}
 
function isOlder(user: User, checkAge: number) {
  return checkAge > user.age;
}
```


##unknown型
* 最終的にどの型になるのかわからないときに使う型です

```ts
let userInput: unknown;
let userName: string;

userInput = 5;
userInput = 'Max';

userName =userInput; //エラー：stringであることが保証されていない
```

* 🌟unknown型を型が指定された変数に代入する時は、型チェックが必要になります
    * 🌟少しでも型が予測できるなら、union型を使いましょう

```ts
if( type0f userInput === 'string' ){
    userName =userInput;
}
```



##never型

* 🌟絶対に、値を返さない時に使う関数の戻り値の型。
    * コード作成者の意図を伝えられるというメリットがあります
    * エラーを投げる、無限ループなどで使います

```ts
function generateError (message: string ,code:number) :void{
  throw{ message:message, errorCode:code} ;//ここでスクリプトがクラッシュする
}

const result = generateError('エラーが発生しました',500);
console.log(result);
```