TypeScriptについて学習しよう②　TypeScriptの文法 vol.1

本記事ではTypeScriptの文法について解説していきます。

TypeScriptそのものについての説明や、導入方法について知りたい方はこちらの記事を参考にしてください。
[TypeScriptについて学習しよう①　TypeScriptの説明と導入方法](https://qiita.com/y-wanida/items/9bcbd1b19403b0f4ec1c "TypeScriptについて学習しよう①　TypeScriptの説明と導入方法")

## TypeScriptにおける変数と定数
変数の宣言に使用される「let」「const」「var」の使い方や概念についてはJavaScriptと同じです。
こちらの記事にて変数の宣言についての説明を記述しているため、もし内容を確認したい方は**JavaScriptにおける変数**という見出しの箇所を確認してください。（変数の命名規則についても同じです。）

[JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント](https://qiita.com/y-wanida/items/a608d9427961b4979e83#javascript%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%A4%89%E6%95%B0 "JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント")

TypeScriptにおける変数の宣言方法は、ざっくりこんな感じです。
JavaScriptとの違いは変数の宣言時に**型の定義**を行っているというところです。

```js
let [変数名]: [変数の型] = [値];
```

下記のような例になります。

```js
let test: string = 'この文字列を変数testに格納しました';
```


## TypeScriptにおける型の設定方法
TypeScriptでは型を設定することによって、JavaScriptよりもコードの可読性を向上させることができます。
基本的な型の設定例は下記です。

### 基本（プリミティブ）型
…言語にあらかじめ用意されている基本的なデータ型のことです。

#### 数値型（number）
…数字を扱う型です。他の言語でいう整数（int）や浮動小数点数（float）を区別せずに扱うことができます。
```js
let integer: number 10; // 整数
let float: number 0.54321; // 少数
```

#### 文字列型（string）
…文字列を扱う型です。シングルクォート（'）、ダブルクォート（"）、バッククォート（`）で囲まれた文字列のことを指します。
```js
let single: string = 'single';
let double: string = "double";
let back: string = `back`;
```

#### 真偽型（boolean）
…真偽値を表します。trueとfalseの２択があります。
```js
let t: boolean = true;
let f: boolean = false;
```

#### シンボル型（symbol）
…一意の識別子を表します。シンボルはオブジェクトのプロパティキーとして使用する場合などに便利です。

```js
let sym1 = Symbol();
let sym2 = Symbol("test");
```
１行目：新しいシンボルを生成します。引数を渡していないため、説明（description）はありません。
２行目：新しいシンボルを生成します。引数として文字列「test」が渡されますが、生成された新しいシンボルの説明（description）として扱われます。

※たとえ、１行目と２行目に、引数として同一の引数「test」を設定しても、説明（description）が同一であるだけで、シンボルとしては重複していません。

Symbolの頭文字が大文字であるのは、ES6で導入された**Symbol**がJavaScriptの組み込みオブジェクトであるためです。（組み込みオブジェクトやコンストラクタ関数は通常、大文字から始まる命名規則にのっとるため）

#### 戻り値が無いという意味の型（void）
…返り値が無いことを示しています。関数が呼び出されたとき、例えばメッセージなどの表示を行うけれども、呼び出し元に値を返さない場合に使用される。

```js
function warn(): void {
    console.log("warning");
}
```
この場合だと、コンソールに「warning」というメッセージを表示するが、関数自体は何も値を返しません。

#### null値を持つ型（null）
…変数内にnullを割り当て、その変数が値を持たないことを示します。
　先ほどのvoidと意味合いが異なるため、要注意です。

```js
let n: null = null;
```

#### 未定義値を持つ型（undefined）
…未定義とは、変数が宣言されたが、まだ値が割り当てられていない状態を指します。このundefindは初期化されていない状態を明示したり、関数の戻り値として設定するために用います。。

```js
let u: undefined = undefined;
```

#### 大きな整数を扱う型（bigint）
…例えば12345678912345789123456789123456789123456789など非常に大きな整数を扱うためのデータ型です。
```js
let big: bigint = 100n;
```

#### 任意の型（Any）
…どんな型の値でも格納できるため、TypeScriptの型チェックを無効にする場合に使用します。
```js
let a: any = 5; // number型の値
a = "aに文字列を格納しました。" // string型の値
a = false; // boolean型の値
```
-----------------------------------------------------------------------

### ユーザ定義型
…開発者が独自に定義する型のことです。TypeScriptでは、インターフェースや型エイリアスを使用して、オブジェクトの形状や複雑な型を定義することができます。これによってコードの可読性・保守性が向上します。

<details><summary>【用語解説】</summary>
<p><b>インターフェース</b><br>…TypeScriptにおいてオブジェクトの形状を定義するための強力なツールのことです。これにより、オブジェクトが持つべきプロパティやメソッドを明確にし、型安全性を高めることができます。</p>
<p><b>エイリアス</b><br>…元々の名前や情報を隠すために使用される別名や偽名のことです。型エイリアスとは、既存の型に別名を付けることです。これにより、複雑な型を簡潔に表現したり、再利用可能な型を定義したりすることができます。</p>
<p><b>オブジェクト</b><br>…元々の名前や情報を隠すために使用される別名や偽名のことです。型エイリアスとは、既存の型に別名を付けることです。これにより、複雑な型を簡潔に表現したり、再利用可能な型を定義したりすることができます。</p>
</details>

#### 配列型（Array）
…配列型は同じ型の要素を持つリストを表します。配列型の表し方は２通りあります。
一行目：**型名[]**
二行目：**Array<型名>**
```js
const numbers: number[] = [1, 2, 3];
const strings: Array<string> = ["a", "b", "c"]; // Arrayは頭文字が大文字であること
```

<details><summary>【用語解説】</summary>
<p><b>配列</b><br>…連なった箱のようなものをイメージしていただけると分かりやすいです。情報をこの配列に入れることで、繰り返し処理で順番に取り出すことができたり、配列のn番目のデータを取り出す等まとまった情報の管理ができます。0始まりなので一番左に格納されている値は0番目となります。</p>
</details>

#### タプル型（tuple）
…固定長の配列で、各要素に異なる型を持たせることができます。一度作成するとその内容を変更できません。
```js
const tu: [string, number] = ["Tarou", 20];
```
上記の例では定数tuにstring型として「"Tarou"」、number型として「20」を設定しています。
配列とは異なる

<details><summary>【用語解説】</summary>
<p><b>タプル</b><br>…複数の構成要素からなる組を表す概念のことです。リストと似ていますが、タプルは一度作成すると要素の追加や削除ができないという特徴があります。</p>
<p><b>固定長</b><br>…データや要素の長さがあらかじめ決まっていて変化しないことを指します。</p>
</details>

#### 列挙型（enum）
…関連する、名前付き定数の集合を定義します。列挙したメンバー（下記でいうWork,Rest,Cook,Sleep）には0始まりで数値が割り当てられます。（Workは0,Restは1...）

```js
enum Task{
    Work,
    Rest,
    Cook,
    Sleep
}
// 列挙型の定義はブロック構造（中括弧{}）で囲まれているため、セミコロンは不要です。
const task: Task = Task.Work; // 定数taskの中にTask列挙型のWorkを割り当てている
console.log(task); // 0が出力される
```

#### インターフェース型（interface）
…オブジェクト構造を定義するために使用されます。インターフェースを使用することで、オブジェクトが持つべきプロパティやメソッドを明確に指定することができます。

```js
interface Student{
    name: string;
    age: number;
    class: string;
}

const student: Student = {name: "Tarou", age:18, class: "A"};
// 定数studentに右辺の情報のまとまりを格納する
```
上記の例では、Studentインターフェースがname、classという文字列プロパティと、ageという数値プロパティを定義しています。studentオブジェクトはこのインターフェースに従って作成されています。

#### ユニオン型
…複数の型のいずれかを取ることができる型です。これにより、変数や関数の引数が複数の異なる型を受け入れることができます。
```js
// 許可できる型がstringとnumberの場合
let tel: string | number;
tel = "1234-1234"; // OK
tel = 12341234;   // OK

// 許可できる型がstringとnumberとnullの場合
let tel: string | number | null;
tel = "1234-1234"; // OK
tel = 12341234;   // OK
tel = null;   // OK
```

### リテラル型
…特定の値だけを許可する型です。先ほどのユニオン型と似た記述方法です。
数値リテラル型・文字列リテラル型・ブールリテラル型が存在します。
**リテラル**とは値そのものという意味合いがあります。
```js
// 数値リテラル型の例
let a: 1| 2| 3;
a = 1; // OK
a = 2; // OK
a = 3; // OK
a = 4; // error
```
上記の例では、aは1,2,3のいずれかしか割り当てることができません。4を格納しようとするとエラーが発生します。

## エスケープシーケンス

**エスケープシーケンス**
…文字列内で特定の特殊文字や制御文字を表現するための文字列のことです。バックスラッシュ（\）と特定の文字を組み合わせて使用します。これにより改行等、画面に直接表示できない文字を表すことができるようになります。使用方法は基本的にJavaScriptと同じなので、下記記事の**エスケープシーケンス**という見出し部分を参照してください。

[JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント](https://qiita.com/y-wanida/items/a608d9427961b4979e83#%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9 "JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント")

## 型推論
…データ型が明らかな場合にはデータ型の指定を省略して良いというルールのことです。
　これによってコードをシンプルにすることができ、可読性が向上します。
 　簡潔に述べるとTypeScript側が勝手に型を推測して型を割り当ててくれる機能です。

例えば、型を設定せずに下記のように変数に値を格納します。typeof()でその変数に入っている値の型が何なのかを判定します。
```js
const fish = 'suzuki';
console.log(typeof(color));

const n = 100;
console.log(typeof(n));
```
画面でDevツールを開き、コンソールの結果を確認してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/a95ddb2e-b7d4-9c30-8b50-0cb99a18dc88.png)

このように型をファイル内で明示していなくても、TypeScript側で自動で推測して、変数内に入っている型を割り当ててくれています。
可読性の観点から、明らかに型を設定せずとも値から推測できる値である場合、コードを省略して記述することが推奨されています。

## 演算子・インクリメント／デクリメント
演算子とインクリメント／デクリメントについてもJavaScriptと同じように記述して使用することができます。
下記記事において詳細を参照してください。

【演算について】
[JavaScriptの基本① JavaScriptの使用方法](https://qiita.com/y-wanida/items/6a92248ac253948e7695#javascript%E3%81%AE%E6%BC%94%E7%AE%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 "JavaScriptの基本① JavaScriptの使用方法")

【インクリメント／デクリメントについて】
[JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント](https://qiita.com/y-wanida/items/a608d9427961b4979e83#javascript%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88%E3%83%87%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88 "JavaScriptの基本② 変数・エスケープシーケンス・インクリメント／デクリメント")

## テンプレートリテラル

**テンプレートリテラル**
…TypeScriptで文字を扱うための機能です。バッククォート（`）で囲まれた文字列で、変数や式を（${}）内に埋め込むことができます。これによって、複雑な文字列操作が容易になります。（この機能はJavaScriptにおいても使用します。以前JavaScriptの記事を作成した際には取り上げていなかったため本記事にて取り上げます。）

```js
const student = "Tarou";
const greeting = `Good Morning ${student}`;
console.log(greeting);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/32893256-9e21-34f0-47bc-a83df438ee3f.png)

ちなみにバッククォートで囲む部分は複数行にすることができます。
```js
const student = "Tarou";
const greeting = `Good Morning ${student}!
How are you?`;
console.log(greeting);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/780fcb3e-53b3-6285-db3d-70addedab9c1.png)