ざっくり入門TypeScript

# 概要
TypeScriptに関して以下の流れでざっくりとまとめました。

- [TypeScriptとは?](#typescriptとは)
- [TypeScriptの利点](#typescriptの利点)
- [インストール](#インストール)
- [コンパイル](#コンパイル)
- [静的型付け](#静的型付け)
- [代表的な型](#代表的な型)
- [インターフェース](#インターフェース)
- [クラスベースオブジェクト指向](#クラスベースオブジェクト指向)


# TypeScriptとは？
`TypeScript`とはJavaScriptを拡張したプログラミング言語で、「`静的型付け`」・「`クラスベースオブジェクト指向`」等の特徴を持ちます。

# TypeScriptの利点
TypeScriptを使用する事には以下の様な利点があります。

- 静的型付けで明らかなエラーを防ぐことが可能で、ディバグもより簡単である。
- クラスベースオブジェクト指向のため、大規模開発においての開発効率コストが削減ができる。

# インストール
`npm`を使用する事で簡単にインストールできます。

```console
$ npm install -g typescript
```
以下のコマンドでインストールが出来た事を確認しましょう。

```
$ tsc -v
$ Version 3.3.3333
```

# コンパイル
TypeScriptのソースコード(`.ts`)は、そのままでは実行できず、JavaScriptにコンパイルしてから実行します。

以下の様に`tsc`を使用する事でコンパイルが可能です。

```console
$ tsc main.ts
```

複数のファイルを指定したり、全てのファイルを指定する事もできます。

```console
# 複数ファイルのコンパイル
$ tsc main.ts workder.ts

# 全ての.tsファイルをコンパイル
$ tsc *.ts
```

`--watch`オプションを使用する事で、指定したファイルに変更がなされたら自動でコンパイルさせる事も可能です。

```console
$ tsc main.ts --watch
```

# 静的型付け
TypeScriptの大きな特徴の1つが`静的型付け`です。
簡単に言うと、__宣言する変数に格納できる型を指定できる機能__です。

下の例を見ると、__変数__、__関数の仮引数__、__関数の返す値__　の全てに型を定義している事がわかります。

```ts:mail.ts
// 変数に型を与えて宣言。
var onigiri: string = 'onigiri', // String型
    calories: number = 200;  // Number型

// 関数の仮引数にも受け入れる型を定義。
// {}の前にあるstringは関数の返す値の型を定義している。
function todaysMeal(food: string, energy: number): string {
  return `My ${food} has ${energy} calories`
}

todaysMeal(onigiri, calories)
```

上記のTypeScriptファイルをコンパイルすると以下の様なJavascriptファイルになります。
Javascriptは型など知らないので、型付け部分は完全に無視されています。

```js
var onigiri = 'onigiri', // String型
calories = 200; // Number型
function todaysMeal(food, energy) {
    return "My " + food + " has " + energy + " calories";
}
todaysMeal(onigiri, calories);
```

もし以下の様な不正なTypeScriptファイルをコンパイルしようとすると、エラーを発生させます。

```ts
// 変数に型を与えて宣言。
var calories: number = 'Calories';  // Number型
```

```console
$ tsc main.ts
main.ts:3:5 - error TS2322: Type '"Calories"' is not assignable to type 'number'..
```

関数に誤った型の値を渡した際にもコンパイル時にエラーを発生してくれます。

```ts
function todaysMeal(food: string, energy: number): string {
  return `My ${food} has ${energy} calories`
}

// Number型のenergyに文字列を渡している。
todaysMeal('FOOD', 'A LOT OF')
```

```console
$ tsc main.ts
Argument of type '"A LOT OF"' is not assignable to parameter of type 'number'.
```

# 代表的な型
`静的型付け`を学んだ所で、TypeScriptで使用される代表的な型を学びましょう。

- `Number`: 全てのNumericの値。
- `String`: 文字列。
- `Boolean`: trueかfalse
- `Any`: この型をもつ変数は全ての型の値を持つ事ができます。
- `Void`: 関数が何も値を返さない時にセットされる型です。

# インターフェース
`インターフェース`はオブジェクトがある構造に合っているかどうかの型チェックに使用されます。
`インターフェース`を定義することによって、変数の特定の組み合わせに名前を付けることができ、それらが常に一緒になることを確実にします。

```ts:interface.ts
// Personインターフェースをとその要素を型と共に定義。
interface Person {
  name: string;
  age: number;
}

// 関数はPersonインターフェースの構造を満たすオブジェクトを受け取る。
function intro(person:Person): string {
  return `My name is ${person.name}. I am ${person.age}!`
}

// Personインターフェースの構造に従う変数を定義します。
var ken = {
  name: 'Ken',
  age: 20
}

// 関数を実行します。
intro(ken) //=> My name is Ken. I am 20!
```

上記のTypeScriptファイルをJavascriptにコンパイルすると以下の様になります。

```js
function intro(person) {
    return "My name is " + person.name + ". I am " + person.age + "!";
}

var ken = {
    name: 'Ken',
    age: 20
};

intro(ken); //=> My name is Ken. I am 20!
```

# クラスベースオブジェクト指向

JavascriptでもES6から`class`を用いた記法が出来るようになりましたが、TypeScriptの`クラスベースオブジェクト指向`とはやや書き方が異なります。

```ts
class Menu {
  items: Array<string>; //文字列の配列を表します。
  pages: number

  constructor(item_list: Array<string>, total_pages: number) {
    this.items = item_list;
    this.pages = total_pages;
  }

  // Method
   list(): void {
     console.log("Our menu for today:");
     for(var i=0; i<this.items.length; i++) {
       console.log(this.items[i]);
     }
   }
}

// Menuクラスのインスタンスを作成します。
var sundayMenu = new Menu(["pancakes","waffles","orange juice"], 1);

// メソッドを呼びます。
sundayMenu.list();
```
また、以下の様にしてクラスの継承が可能です。

```ts
// Menuクラスのインスタンスを作成します。
var sundayMenu = new Menu(["pancakes","waffles","orange juice"], 1);

// メソッドを呼びます。
sundayMenu.list();


class HappyMeal extends Menu {
  // Properties は省略可能だがconstructorは定義する必要あり。
  constructor(item_list: Array<string>, total_pages: number) {
    super(item_list, total_pages);
  }
}

// HappyMealクラスのインスタンスを作成
var menu_for_children = new HappyMeal(["candy","drink","toy"], 1);

// 継承されたメソッドを実行。
menu_for_children.list();
```

# Generics(ジェネリックス)

Generics(ジェネリックス)に関しては別ポストにまとめました。

[【TypeScript】Generics(ジェネリックス)を理解する](https://qiita.com/k-penguin-sato/items/9baa959e8919157afcd4)

# 参照
- [Learn TypeScript in 30 Minutes - Tutorialzine](https://tutorialzine.com/2016/07/learn-typescript-in-30-minutes)
- [TypeScript Deep Dive](https://basarat.gitbooks.io/typescript/)