【TypeScript】TypeScriptの概要・主要な型

#TypeScriptとは
* TypeScriptとはJavaScriptを拡張したプログラミング言語です
* コンパイルして、ブラウザやサーバサイドで認識できるjavascriptに変換されます

##TypeScriptの特徴・メリット
* 型（Type）を厳密に定義することで、エラーをコンパイル時に発見できる<br>
　cf：JavaScriptの型は、コンパイル時にチェックされ、JacaScriptは実行時にチェックされる
* 古いブラウザで最新のJavaScript世代のコードを動かせる（Babelのような機能）
* JavaScriptに存在しない新機能が使用できる（インターフェース、ジェネリクス）
* メタプログラミングができるが使える（デコレータ）
* 豊富なコンパイルなどの設定オプションが使える（高カスタマイズ性）
* TypeScriptではないプロジェクトでも役立つモダンなツールが使える（IDEの裏側で動かすことができる）

#TypeScriptの基本的な型

| 型 | 説明 |
|:-:|:-:|
| number | 整数や浮動小数点を含む全数値 |
| string | 文字列 |
| boolean | true, false |
| object | object型を定義する<br>(JavaScriptのobject) |
| Array | 型を柔軟/厳格に定義できる配列<br>(JavaScriptのArray)  |
| Tuple | 要素の型と要素数を明確に指定できる配列 |
| Enum  | 列挙型 |
| Any | 型指定なし  |

##object型
* オブジェクト型は、key => type でプロパティを指定します

```ts

//ベストプラスティス(型推論)
const person:{
    name: 'neko';
    age:  30;
};

//以下のように型推論される
const person:{
    name: string;
    age: number;
}

```

* 明示的に型指定をすることも可能<br>
(JavaScriptには、型情報が出力されないのでベストプラスティスではない)

```ts

const person: {
    name: string;
    age: number;
} = {
    name: 'neko';
    age:  30;
}

// ageは30しか入れられない
const person: {
    name: string;
    age: 30;
} = {
    name: 'neko';
    age:  30;
}
```


##Array型
* 型を指定した配列を作れます

```ts
let favActivities : string[] ; //stringの配列

for ( const hobby of person.hobbies ){
  console.log(hobby.toUpperCase); //Stringのみ使えるメソッドを使える
}

```

* any型を使い、型をミックスした配列も定義可能 (その分型チェックの恩恵は少ない😿)

```ts
 let favActivities : any[] ; //どんな型の配列でもOK
```

##Tuple型

* 🌟配列に対して、明示的に、正確に要素の型と要素数を指定できるというメリットがある

```ts
//roleに数字と文字列を格納したい場合

const person:{
    name: 'Neko',
    age:  2,
    hobbies: ['Sports' , 'Cooking'],
    role: [2 , 'author'],  // (string | number と型推論される) 
};

//role配列では、型推論の不完全性によるバグが発生してしまう

person.role.push('admin'); // roleには、stringかnumberが入るということしか知らないので、2個以上の値も詰められる
person.role[1]=10; //  index 1 の配列に、10を入れることができてしまう

```

* 🌟Tuple型では、明示的に型を定義することができる！

```ts

const person:{
    name: string;
    age: number;
    hobbies: string[];
    role: [number, string]; //tupleでの型指定:2個の要素を持つ配列を認識される
} = {
    name: 'Neko',
    age:  2,
    hobbies: ['Sports' , 'Cooking'],
    role: [2 , 'author'],  
};


//roleの型と長さを定義したことでエラー検知できる

//person.role[1]=10; // 型が違うのでエラー
//person.role =[] //長さが合わないのでエラー
//person.role =[2 , 'author' , 'user' ] //長さが合わないのでエラー

person.role.push('admin'); //pushはエラー検知できない

```

##Enum型
* 🌟定数の集合を人間がわかりやすい名前をつけて管理できる
* 🌟定数のリストには自動でnumberが当てられる
    * 初期数値を手動で設定することも可能


```ts

//Enum型を使わない場合は、定義した文字列を頭で覚え、いちいち定数作成して管理しないといけない

const person = {
    name: 'Neko',
    age:  2,
    hobbies: ['Sports' , 'Cooking'],
    role: 'READ ONLY USER',   //文字列を覚えないといけない
};

const ADMIN = 0; //面倒...
const READ_ONLY = 1; //面倒...
const AUTHOR = 2; //面倒...

```

* 🌟そこでenum型を使って独自変数を作って、変数を管理する（Roleというカスタム型を作成）

```ts

enum Role{ //自動で0,1,2の数字がつく
ADMIN,
READ_ONLY,
AUTHOR
}

const person ={
    name: 'Neko',
    age:  2,
    hobbies: ['Sports' , 'Cooking'],
    role: Role.ADMIN,   //enum型を使う
};

//if文でもenum型を使える

if (person.role == Role.ADMIN){…}

```

```ts

//enum型宣言時に初期値を設定可能

enum Role{ 
ADMIN =5,  //5
READ_ONLY, //6
AUTHOR,    //7
}

//全部に初期値を設定した場合
enum Role{ 
ADMIN =100, 
READ_ONLY = 200, 
AUTHOR = 300, 
}

//数値以外も設定可能
enum Role{
ADMIN = 'ADMIN', 
READ_ONLY= 'READ_ONLY', 
AUTHOR =100, 
}
```