【TypeScript】TypeScript で es6 の機能を使う方法


###🌟TypeScript で es6 の機能を使う方法をまとめました🌟
※tsconfigのコンパイル設定をes5にすると、出力JavaScriptはes5の仕様になります

* const/let 
* アロー関数 
* スプレッド演算子 
* rest パラメータ
* 分割代入 


# const ・ let
* const は、定数で、let は変数です

### 変数であるletと、従来のvarの違い

* var : ブロックスコープが無く、グローバルスコープか関数スコープのみ
    * 関数の外で宣言された変数は、関数の外でも使える
    * 関数の中で宣言された変数は、関数の中のみで使える
* let : ブロックスコープがある

```ts
if ( age>=20 ){
  var isAdult = true;
}

console.log(isAdult ) //OK
```


```ts
if (age >=20 ){
  //ブロック変数であるisAdultは、このブロック中のみでアクセスでき、その外ではアクセスできない
  let isAdult = true;
}

console.log(isAdult ) //NG
```

# アロー関数
* 関数を短く書くことができる方法です

```ts
const add = (引数) =>  {関数の本体};
```

```ts

const add = ( a: number, b:number ) =>  {
    return a + b;
};
console.log(add(2,5));
```

###関数記述の省略方法

* 関数の中身が1式の結果のみを返すときは、中括弧とreturnを省略可能

```ts
const add = ( a: number, b:number ) =>  a + b;
console.log(add(2,5));
```

* 引数が一個のときは()を省略可能

```ts
//outputが暗黙的にanyになってしまう
const printOutput = ( output: string | number ) => {
   console.log(output);
};
```


```ts
//constの型を関数の型として定義すると、outputも型推論される
const printOutPut : ( output: string | number ) => void = output  => {
   console.log(output);
};
```


* click時のeventで引数部分 `(引数) => {関数の本体};` を省略するときなどに使えます〜(^o^)


```ts
const button = document.querySelecter('button');

if (button) {
   button.addEventListener('click', event =>{ //引数のみを書くことができる！
    console.log(event);
   });
}
```



# 引数のデフォルト値
* 関数の引数にデフォルト値を設定することができます
* TypeScript 自体はデフォルト値があるかどうかを判定できないため、デフォルト値は、2番目の引数のみ設定できます
* つまり2番目の引数、もしくは全部のパラメータにデフォルトを設定することが可能です

```ts
const add = ( a: number, b:number =1 ) =>  a + b;
console.log(add(2));

//NG
const add = ( a: number = 1, b:number ) =>  a + b;
console.log(add(2)); //引数の2は、1番目の引数aのパラメータになってしまう
```


#スプレッド演算子
* 配列やオブジェクトの要素を展開することができます
* array やobject から、値を取り出す時に便利です(^o^)

```ts
const hobbies = [ 'Sleeping' , 'Cooking' ];

const activeHobbies = [ 'sleeping heavily' ]; //constなのは、配列の参照のみで、値は追加可能

activeHobbies.push( hobbies[0] , hobbies[1] ); //一個一個追加するのは面倒。。

//スプレッド演算子で、中身を全部展開して、個別の値として追加する
activeHobbies.push( ...hobbies );
const activeHobbies = [ 'sleeping the whole day', ...hobbies ]; 
```

* スプレッド演算子でオブジェクトをコピーすることも可能です

```ts
const cat = {
  name: 'Neko',
  age: 3,
};

//オブジェクトのキーバリューを全部とってきて、別のオブジェクトにコピーする（参照先は同じ）
//= 空のオブジェクト作成しオブジェクトの中身をコピーする

const copiedCat = {
  ...person //参照のコピー
};

```

#restパラメータ
* 可変長の引数を受ける関数を定義することができます

###restパラメータとスプレッド演算子
* restパラメータ：`...`が関数パラメータの最後にある場合は restパラメータです。リストの残りを配列にマージします
* スプレッド演算子：関数呼び出しなどで`...`があると "スプレッド演算子" です。配列をリストに展開します
* ex: 任意の数の引数を受け取る関数を作ります

```ts
//関数に渡されたパラメータが1配列にマージされて渡されることになる

const add = (...numbers: number[] ) => {
    let result = 0;
    numbers.reduce( () => {}, 0 )
}; 

const addNumbers = add(5, 10, 2, 3.7 ); //任意数の引数を指定

```

###reduceメソッドで引数を受け取る方法
* reduceメソッドは配列に使えるメソッドで、要素を一個ずつ処理することができます

```
reduce( (引数) => {計算を行う関数} ,初期値 )
```

```ts
const add = (...numbers: number[] ) => {
    return numbers.reduce( (curResult , curValue) => { //returnで配列の合計値を返す
        return curResult + curValue;
    } ,0 );
}; 
```

###タプルでも受け取れる
* 引数の型が決まっている場合、タプルを使うと、より型安全です

```ts
const add = ( ...numbers : [ number , number, number ] ) => {
    return numbers.reduce( (curResult , curValue) => { //returnで配列の合計値を返す
        return curResult + curValue;
    } ,0 );
}; 

const addNumbers = add( 5, 10, 2 ) ;
```

#分割代入
* 変数宣言と同時に、配列の要素の値を代入する事ができます！(^o^)

```ts
//分割代入を使わずに変数を一個一個宣言するのは面倒。。
const hobby1 = hobbies[0];
const hobby2 = hobbies[1];
```

```ts
//分割代入で、変数宣言と同時に配列の要素の値を代入
const [ 配列の中身を格納したい名前 ]  = 配列 ; 
```

```ts
const [num1, num2] = [1, 2];
console.log(num1,num2); // 1 2

const [hobby1 , hobby2, ...remainingHobbies ]  = hobbies ; 

//分割代入しても、元の配列は変更しない
console.log( hobbies, hobby1, hobby2 );
```

###オブジェクトの分割代入

* ex: catオブジェクトから、存在するプロパティを指定して、値を取り出します

```ts
const cat = {
  firstName: 'Neko',
  age: 3,
};

const { firstName, age } = cat; 
```

* 分割し格納する変数の名前を変更することができます

```ts
const { firstName: userName , age } = cat; 

console.log( userName , age , cat );  //firstNameは存在しない
```