C/Java/C#(SI系)なエンジニアに贈るTypeScript事始め その3（型の整理(基本編))

## TypeScriptにおける型をもう少しだけ。
だいぶ仕事にかまけてサボってしまいましたが、ゆっくり続けていきます。


## 型の基本
だいたい想像通りです。オブジェクト指向な言語を触ってきた私たちなら問題なく対応可能です！

### 型の種類

| 型      | 属性|説明                      |
|---------+----|-----------------------|
| number  |基本型|数値型(整数/浮動小数点数) |
| string  |基本型| 文字列型                  |
| boolean |基本型| 真偽型(true/false)        |
| symbol  |基本型| シンボル型                |
| any     |オブジェクト型| 配列、タプル、クラス、インターフェイス、関数など      |
Java脳だとsymbolとanyがよくわからないですね。オブジェクト型は別途整理します。

### オブジェクト型ってなに？
オブジェクト指向言語をやってきた人たちならなんとなくわかると思いますが、カンタンに整理します。

#### 配列
配列です、、、宣言の仕方が複数種類あリます。[]で宣言するやり方とArrayで宣言するやり方。Array使うと混乱するケースがあるようなので普通に[]で宣言する、と覚えましょう。

```typescript:ArraySample.js
//配列
let neta: string[] =　['マグロ','イカ','車海老','ウニ','サーモン'];

//これも配列(ジェネリックス記法))
let sake: Array<string> = ['ビール','焼酎','日本酒','ワイン'];

//多次元配列はArrayでは宣言できないよ
let neta_from: string[][] = [
    ['マグロ', '大間'],
    ['イカ',   '三崎'],
    ['ウニ',   '淡路島'],
];

//Arrayだと混乱する例。初期値を期待しているのかサイズを期待しているのかが不明瞭。
let array1: number[] = new Array(5);       //サイズ5の空配列
let array2: number[] = new Array(5,10,15); //要素5,10,15からなるサイズ3の配列
let array3: number[] = new Array(-1);      //これは実行時エラー！

//空配列を宣言するときはこう書こう
let array4: number[] = [];
```

#### 連想配列（ハッシュ)
JavaでいうHashMapです。ハッシュをカンタンに取り扱えるのはスクリプト言語の有利な点だと勝手に思っています。Perlの連想配列とかすごくお世話になりました。

```typescript:HashSample.ts
//連想配列
let neta_prices: {[index: string]: number; } ={
    'マグロ': 100,
    'イカ': 200,
    '穴子': 250,
    'キュウリ': 50,
};

neta_prices.ウニ = 500;                //こんなにラクに要素を足せるよ！

console.log(neta_prices.マグロ);       //100
console.log(neta_prices['イカ']);      //200
console.log(neta_prices['ウニ']);      //500
```
interfaceキーワードを使えば名前付きの型をあらかじめ用意しておくことができます。C言語でいうtypedefです笑。

```typescript:InterfaceSample.ts
interface animal_colors {[index: string]: string;};
```

連想配列においても型推論による問題が発生する可能性があります。インデックスシグニチャは省略しない！と覚えておきます。先ほどのネタの値段リストで試すとこうなります。

```typescript:HashSampleError.ts
let neta_prices2 = {
    'マグロ': 100,
    'イカ': 200,
    '穴子': 250,
    'キュウリ': 50,
};

neta_prices2.ウニ = 500;             //コンパイルエラー!

//- error TS2339: Property 'ウニ' does not exist on type
// '{ 'マグロ': number; 'イカ': number; '穴子': number; 'キュウリ': number; }'.
```

これはどういうことかというと、インデックスシグニチャが存在しないため、型推論がされた結果、ハッシュではなく、４つのメンバー（マグロ、イカ、穴子、キュウリ）を持ったオブジェクト型である、と推論されてしまったということなのです。なので、ウニというメンバーはいませんぜ！というエラーが発生するわけですね。

#### 列挙型（enum)
これも他の言語でもよくありますよね。普段通りに使えます。

```typescript:EnumSample.ts
enum Sex {
    MALE,                 //初期値を指定しない場合は0からの連番
    FEMALE,               //1
    UNKNOWN = 9,          //初期値を指定したので9
};

let m: Sex = Sex.MALE;
console.log(m);           //0
console.log(Sex[m]);      //MALE
```

#### タプル(Tuple)
複数の異なる型の集合を表現するためのデータ型です。これは意外だったのですがタプルもあんまり使わない方が良いんですって。クラスオブジェクトとして定義した方が自然で管理がラク、という評価のようです。

さらに、先頭の要素を削除する等、データの構造を変えたりするとパニックになります。要素を削除してもデータ型には反映されないため、容易に実行時エラーが発生することとなってしまいます。

```typescript:TupleSample.ts
let tuple_data:[string, number, boolean] = ['獺祭',1200, false];
console.log(tuple_data);                //[ '獺祭', 1200, false ]

//各要素の肩に応じたメソッドの呼び出しが可能です
console.log(tuple_data[0].length);      // 2
console.log(tuple_data[1].valueOf());   // 1200
console.log(tuple_data[2] === false);   // true

tuple_data.shift();                     //先頭要素の削除はできるが、、
                                        // 実データと型データがズレてしまう・・・
console.log(tuple_data[0].length);      // undefined
console.log(tuple_data[1].valueOf());   // false
console.log(tuple_data[2] === false);   // false
```
### Symbol型ってなに？

ECMAScript 2015で導入されたもので、number, stringと同様に使えます。
以下の特徴を持った型です。オブジェクトのプロパティのキー値に使ったりするらしい。
色々な使い方ができそうなので、別途まとめます。今はさわりだけ。

- 不変(immutable)
- 一意(unique)

```typescript:SymbolSample.ts
const NAME = Symbol('kuzukawa')
const NICKNAME = Symbol('kuzukawa')

// if(NAME === NICKNAME) はコンパイルエラー。trueになることはない

console.log(NAME)               //Symbol(kuzukawa)
console.log(NAME.toString())    //Symbol(kuzukawa)
console.log(NAME.valueOf())     //Symbol(kuzukawa)
```

### 型アサーション, TypeAssertion(キャスト)
以下の２通りの書き方ができます。とりあえず使ってはいけない機能、とだけ覚えておきます笑
Javaでもキャストは止めようねって話でしたよね。

```typescript:TypeAssertiionSample.ts
function show(result: string) {
    return `今日は${result}点な気分です。`;
}

console.log(show('100'));          
console.log(show(<any>100));      // <Type> Value
console.log(show(100 as any));    // Value as Type
```
## まとめ
今回は基本的な型の整理だけを行いました。まだ整理できていない型の話がいっぱいあるのでまだまだ型の話を続けようと思っています。SI業界の方は静的型付けな世界で育っていることが多いような気がしていますが、時代は静的型付け言語！ですし、意外とスムーズに頭に入ってくる初見です。

## おまけ(リテラルの書き方ざっくり)
### 数値リテラル
| 種類   | 概要                 | 例            |
|--------+----------------------+---------------|
| 10進数 | 一般的な10進数表現   | 1, 392, 10012 |
| 16進数 | 0xをプレフィックスに | 0xFF, 0x31b1  |
| 8進数  | 0oをプレフィックスに | 0o123, 0o777  |
| 2進数  | 0bをプレフィックスに | 0b0101010101  |
| 指数   | 仮数 E 符号 指数     | 3.5E2         |

いつもと対して変わらないので説明は省略しますね。

### 文字列リテラル
| 種類             | 概要       | 例             |
|------------------+------------+----------------|
| シングルクォート | ' でくくる | 'Hello Sushi!' |
| ダブルクォート   | " でくくる | ”マグロうまい” |
| バッククォート   | ` でくくる | `${neta}一貫`  |

バッククォートでくくる形を「テンプレート文字列」と言います。

- 文字列に変数を埋め込める
- 複数行も表現可能

といういいヤツです。+で文字列連結！なんてもう今は昔。

```typescript
let sushi = "寿司";
let sushi2 = "鮨";
let msg: String = `
世の中で一番ウマい食べ物が鰻なのは
いうまでもないが、スシ勢という勢力もおり
    ${sushi}　と書くのか
    ${sushi2}　　と書くのか
今でも局地的に論争がされている`;

console.log(msg);
```

それではまた次回。