TypeScriptハンズオン 学習メモ 2.値・変数・構文をマスターする

# 値と変数

## TypeScriptプレイグランドを使ってTypeScriptを試す

https://www.typescriptlang.org/ja/play

## 基本の型

- number
    - 数値（64bit浮動小数型）
- string
    - テキスト
    - シングルクォートとダブルクォートは全く同じ
    - バッククオートは値の中で改行が可能
- boolean
    - 真偽値(true / false)


## 定数と変数

- const
    - 定数
- let, var
    - 変数
    - 基本letを使う

## 型アノテーション

- `let 名前:型`
- 異なる型の値を入れようとするとエラーとなる

```ts
// 自動的に型を割り当てる
let x = 123
// 型を宣言する
let x:number
```

- any型（なるべく使用しない）
    - `let x` は `let x:any`と同じ
    - エラーとならない

```ts
let x
x = 123
x = "OK"
```

- 特殊な型
    - null
        - 値が存在しない
    - undefined
        - 値が用意されていない。変数を宣言したが、値が代入されていないなど。
    - NaN
        - 数値の演算ができない。数値でないものを演算しようとしたなど。


## 値の変換について

- Number("123")
    -  テキストを数値に変換
- String(456)
    - 数値をテキストに変換

## 演算を行う

- JavaScriptと同じなので省略

# 制御構文

- if、三項演算子、switch、while、for
- JavaScriptと同じなので省略

# 複雑な値

## 配列

```ts
// dataは、型推論でnumber[]型になる
const data = [10, 20, 30]
```

### 変更不可な配列

- 型名の前に`readonly`を付ける

```ts
const data1:number[] = [10, 20, 30]
const data2:readonly number[] = [10, 20, 30]

data1[0] = 100 // エラーとならない
data2[0] = 100 // エラー
```

### 配列ではfor of を使う

```ts
const data:number[] = [10, 20, 30, 40]

let total = 0
for (let item of data) {
    total += item
}
console.log("合計", total)
console.log("平均", total / data.length)
```

## タプル型

- 色々な型の値をひとまとめにする
- 異なる型の値を入れようとするとエラー
- 配列と同じように取り出せる。例 `me[0]`

```ts
let me:[string, number]
let you:[string, number]

me = ["taro", 30]
you = ["hanako", "hanako@example.com"] // エラー
```

## enum型

- `enum 型名 { 項目1, 項目2, ... }`

```ts
enum janken { goo, choki, paa }

const you = janken.goo

switch(you) {
  case janken.goo:
  console.log("あいこです")
  break
  case janken.choki:
  console.log("あなたの勝ち")
  break
  case janken.paa:
  console.log("あなたの負け")
  break
}
```

## 型エイリアス

- 型に別名を付ける
- `type 新型名 = 型名`

```ts
type name = string
type age = number

let me:[name, age]

me = ["taro", 20]

console.log(me)
```

## typeで型を定義する


```ts
type name = string
type mail = string
type age = number

type person = [name, mail, age]


const taro:person = ["taro", "taro@example.com", 30]

console.log(taro)
```

## リテラル型

- okしか値がない型（これだけだとあまり使い道がなく、条件型との組み合わせで使用する）

```ts
type a = "ok"
```

## 条件型（Conditional Types）とは？


- 複数のいずれの型（enum型のように使える）
- ` type = 型1 | 型2 | .... `

```ts
type msg = "hello" | "bye"

const msg1:msg = "hello"
const msg2:msg = "goodbye" // エラー 
```

## 型のチェック

- `typeof(変数)` で型名が取得できるが、基本型のみ

```ts
type msg = string | number

const msg1:msg = "hello"
const msg2:msg = 222

console.log(typeof(msg1))  // "string" 
console.log(typeof(msg2))  // "number" 
```

## ユーティリティ型

- ユーティリティ型とは、型にさまざまな性質を付加する特殊な型
- 多くのユーティリティ型があるが、そのほとんどがオブジェクトで利用するもの
- ここでは、`Readonly`型を試す

```ts
type data = [string, number]
type ReqData = Readonly<data> // ユーティリティ型のReadonly型を使用する

const member1:data = ["taro", 20]
const member2:ReqData = ["hanako", 30]

member1[1] = 21 // エラーとならない
member2[1] = 31 // Readonly型のためエラー
```

## シンボル

- 絶対にかぶらないユニークな型

```ts
const symbolA = Symbol("ok")
const symbolB = Symbol("ok")

console.log(symbolA === symbolB) // false
console.log(typeof(symbolA)) // "symbol"
```

## nullかもしれない値

- nullかもしれない
    - `?`をつける（ただし、?を付けない型の前に入れてはいけない）

```ts

type data = [name: string, age?: number]

const taro:data = ["taro"]
const jiro:data = ["jiro", 30]

console.log(taro)
console.log(jiro)
```