【第2回】React勉強_20230130～

# 第2章 TypeScriptの基礎
## 2.1 TypeScriptの基礎知識
- Microsoft社が開発している静的型付け言語のAltJS
- TypeScriptの特徴
    - 型定義
    - インターフェースとクラス
    - null/undefined安全
    - 汎用的なクラスやメソッドの型を実現するジェネリック
    - エディターによる入力補完
    - ECMAで定義されているJavaScriptの最新仕様
        - TypeScriptはブラウザに先行してECMAの最新仕様を取り入れている
    - JavaScriptと上位互換性あり（JavaScriptのコードがTypeScriptとして動作する）
- TypeScriptのコマンドラインツールによるコンパイル
    - Node.jsをインストールする。npmもインストールされる
    - TypeScriptのCLI（tsc）をインストール
```
$ npm install -g typescript
```
## 2.2 型定義
- TypeScriptでは変数や引数名の後ろに”：”型のように型注釈と呼ばれる型情報を付与する（例）name: string
- 変数の定義
    - let 変数名: 型 = 値
    - const 変数名: 型 = 値
    - letとconstはブロックスコープ、varとは異なる。varは変数を含む関数でも利用可能
    - モダンフロントエンド開発ではlet、constが利用される
    - var、let、constの再宣言、再代入時の挙動

| 変数 | 再宣言 | 再代入 |
|:-:|:-:|:-:|
| var | 可 | 可 |
| let | 不可 | 可 |
| const | 不可 | 不可 |
- 配列
    - string[]などプリミティブ型のあとに[]
    - ジェネリックによる表記も可能Array<string>
    - 複数の型を要素に持つ配列はUnion型やタプルで定義
        - (Stirng|number)　//Union型
        - [string, number]
- オブジェクト
    - let 変数名: {キー名1: 型1; キー名2: 型2, ・・・} = オブジェクト
    - const 変数名: {キー名1: 型1; キー名2: 型2, ・・・} = オブジェクト
    - キー名の末尾に?をつけることでoptionalになる
- 関数
    - function 関数名(引数1: 型1, 引数2: 型2, ・・・): 戻り値の型{ //関数の処理内容 }
    - 引数名の末尾に?でoptional、デフォルト値は"引数: 型 = 初期値"で指定 
    - アロー関数
        - let 関数名 = (引数名: 引数の型): 戻り値の型 => 処理内容
    - 関数を引数にする場合
        - function 関数名(引数にする関数名(引数: 型 => 返り値の型)：戻り値の型{ //関数の処理内容}

## 2.3 基本的な型の機能
- 型アサーション
    - TypeScriptが型推論で具体的な型を推論出来ない場合がある
    - 明示的に型アサーションを利用して、型を指定することができる
    - anyに一旦変換し、次に具体的な型に段階的に変更する使い方もされる
- 型エイリアス
    - type 型名 = 型
    - 型名は通常大文字から始める
    - 例）type Point = {x: number; y: number}
    - オブジェクトや関数に型エイリアスを定義し、可読性を高めることができる
    - オブジェクトのキー名や数を明記せずに利用した場合に型エイリアスが利用できる
        - type 型名 = { []: 型名}
        - 例) type Lable = { [key: string]: string }
- インターフェース
    - interface インターフェース名 {プロパティ名1: 型1; プロパティ名2: 型2; ・・・}
    - プロパティは後で追加可能
    - implementsでクラスに移譲する
    - extendsで拡張可能 
- クラス
    - class クラス名 {フィールド1: 型1; フィールド2: 型2; ・・・}
    - extendsで他のクラスを継承することが可能
    - implementsでインターフェースを実装することが可能
    - アクセス修飾子

| アクセス修飾子 | アクセス可能な範囲 |
|:-|:-|
| public | 全てのクラスからアクセス可能 |
| protected | 現在のクラスとサブクラスからアクセス可能 |
| private | 現在のクラスのみアクセス可能 |
| 指定なし | publicになる |

## 2.4 実際の開発で重要な型
- Enum型(列挙型)
    - enum 列挙型名 {key1, key2, key3, ・・・} //数値型のenum、key1から0,1,2,・・・となる
    - enum 列挙型名 {key1 = '文字列1', key2 = '文字列2', key3 = '文字列3', ・・・} //文字列型のenum
- ジェネリック型
    - クラスや関数において、その中で使う型を抽象化して一旦定義し、実際に利用する際に型を具体的に決めるときに利用される
    - Reactコンポーネントもジェネリック型のクラスとして定義されており、propsで型が外部から指定される
- Union型とIntersection型
    - Union型（型1 | 型2）：和集合　⇒　型1または型2を意味する
        - type Type3 = Type1 | Type2の場合、Type3はType1またはType2のどちらかにあてはまれば良い
    - Intersection型（型1 & 型2）: 積集合　⇒　型1と型2のマージ
        - type Type3 = Type1 & Type2の場合、Type3はType1とType2の全てのプロパティを持つ必要がある
- リテラル型
    - let 変数: 許可するデータ1 | 許可するデータ2 | ・・・
    - 変数に決まった文字列や数値しか設定できないよう制御する
- never型
    - 発生しない値の種類を表す
    - if文やswitch文でTypeScriptの型の条件分岐に漏れがないかを確認できる

## 2.5 TypeScriptのテクニック
- Optional Chaining
    - nullまたはundefinedの場合でも処理をエラーにならずに実行できる
    - Optionalなプロパティでオブジェクトを定義した際、そのオブジェクトのOptionalなプロパティにアクセスする際に?を利用する
        - 例）obj1.property1?.a
- Non-null Assertion Operator
    - 通常コンパイラオプション--strictNullChecksを指定してコンパイルする場合、nullの可能性のあるオブジェクトにはエラーとして扱う
    - nullでないことを明示的にコンパイラに伝えるためにNon-nullを示したい変数などに"!"をつける
    - コンパイラにエラーを起こさなくてよいというだけで、実行時にエラーが出る可能性があることに留意すること
- 型ガード
    - if文やswitch文の条件分岐で型チェックを実施した後、条件分岐ブロック以降は条件に合致した型に絞り込まれて評価される（型推論）
    - オプショナルなプロパティにアクセスする場合に、if文でnullチェックした後はnull safetyなプロパティとして扱える
- keyofオペレーター
    - 型の持つプロパティをリテラルとして返す
```
interface User{
    name: string;
    age: number;
}

type UserKey = keyof User // 'name' | 'age'
```

- インデックス型
    - オブジェクトのプロパティが可変の場合に型定義をまとめて出来る
```
type Obj = {
    [array: string]: string // インデックス型、プロパティは可変で値は文字列
}
```

- readonly
    - 型エイリアス、インターフェース、クラスでreadonlyプロパティを設定でき、設定されたプロパティは変更不可となる
    - ジェネリック型のReadOnly型 ReadOnly<T>

```
type User = {
    readonly name: string;
}

let user: User = { name: 'Ichiro' }
```

- Unknown
    - 任意の値を代入できる型
        - anyと似ているが、anyより不明な値を示すということを強調したもの
        - anyとの違いは代入された値はそのままでは任意の関数やプロパティにアクセスできない
- 非同期のAsync/Await
    - 非同期APIのPromiseの簡易版
- 型定義ファイル
    - JavaScriptのモジュール（例えば、外部のJavaScriptライブラリ）に対して、型情報を付与するファイル
    - 導入方法
        - @typesに代表される公開済みの型定義ファイルを導入する
            - 型定義ファイルもライブラリ内に含まれる可能性あり。その場合、インストール不要
        - 型定義ファイルを自作する
            - 型定義ファイルがライブラリに同梱されていなかったり、公開されていない場合もある。その場合、自作となる
            - 自分で.d.tsという拡張子の型定義ファイルを設置し、読み込ませる
    - 型定義ファイルの導入
```
$ npm install --save-dev @types/ライブラリ名
```

## 2.6 TypeScriptの開発時設定
- tsconfig.json
    - コンパイルに必要な設定やファイル情報を記述したファイル
    - tsc --initコマンドでデフォルトを作成し、プロジェクトルートに配置する
    - 参考URL
        - https://www.typescriptlang.org/tsconfig
- Prettier
    - フォーマッター
    - 導入方法
        - npm install prettier --save-devでインストール
        - フォーマットの設定値ファイル（.pretterrc）をプロジェクトディレクトに配置
        - package.json内のscriptsにprettierの情報を追加
        - $ npm run prettier -formatでフォーマットを実行


```
// package.jsonの設定
{
    "scripts": {
        "prettier-format": "prettier --config .prettierrc 'src/**/*.ts' --write"
    }
}
```

- ESLint
    - 静的解析ツール
    - 解析ルールの設定を.eslintrc.jsに記述する
    - 参考URL
        - https://eslint.org/docs/rules
        - https://eslint.org/docs/user-guide/getting-started
- コンパイルオプション
    - nolmplicitAny
        - 暗黙的なanyを利用するとコンパイルエラーにできる
    - strictNullChecks
        - nullやundefinedに対して、明示的に許容するようにコードを記述しないとコンパイルエラーとなる
    - target
        - コンパイル時にECMAScriptのバージョンを指定して出力できる
        - ブラウザの互換性を保つために利用する


***

# 学習記録
- 学習日/学習時間
    - 2023/1/30（0.5h） 
    - 2023/2/1（0.5h）
    - 2023/2/2（0.2h）
    - 2023/2/3（1.25h）
    - 2023/2/4（0.25h）
    - 2023/2/5（0.5h）