TypeScriptの超きほん　〜TypeScriptってなに？〜

# TypeScript（タイプスクリプト）ってなに？
`TypeScript`はMicrosoftが`JavaScript`を拡張して開発したプログラミング言語です。

ざっくり言うと、**静的型付け言語**になった`JavaScript`と言えるでしょう。

`React`や`Vue`など人気の`JavaScript`フレームワークにも対応しており、活躍の場が広がっています。

> **静的型付け言語**
> 変数の宣言時に**あらかじめデータ型（data type）を設定**する言語。
C/C++やJava、Goなどがある。
>
> 対義語は「**動的型付け言語**」で、JavaScriptやRuby、PHP、Pythonなどがある。

# TypeScriptの特徴
`TypeScript`の特徴やメリットを紹介します。

- 実行時はJavaScriptに変換される
- 既存のJavaScriptと併用できる
- エラーに気づきやすくデバックしやすい

## 実行時はJavaScriptに変換される
`TypeScript`は**トランスコンパイラ**の機能をもっており、

`TypeScript`で書かれたコードは、実行前にすべて`JavaScript`に変換してから実行します。

![0318-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323790/38baebba-4335-b34d-4c2e-36bb6d76941d.png)


変換後のバージョンも選択できるため、実行環境がアップデートされていない現場でも`TypeScript`でモダンな開発をすることが可能です。

> **トランスコンパイラ**
> ソースコードを機械語に変換する「コンパイルラ」に対し、同水準の言語に変換する機能を「トランスコンパイラ」と呼ぶ。
> JavaScriptをトランスコンパイルするBabelなどが有名。

## 既存のJavaScriptと併用できる
`TypeScript`は`JavaScript`を拡張させた言語であるため、`JavaScript`の構文をすべて利用できます。

また、既存コードの一部分を`TypeScript`に置換して、`TypeScript`と`JavaScript`を共存させることもできます。

これは前述した通り、「実行時にすべて`JavaScript`に変換される」ためです。

![0318-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323790/3c48a758-7175-441d-073b-8d20d21a44d8.png)

## エラーに気づきやすくデバックしやすい
これは静的型付け言語の特徴でもありますが、**実行前に構文や型の検証ができます**。

（逆に言えば、JavaScriptなどの動的型付け言語は、実行するまで型エラーが発生するか確認できません）

また、データ型がコードで一目瞭然であり、他者からみてもコードの意味が読み取りやすくなります。

このように、`JavaScript`と比較して`TypeScript`はデバックしやすい特徴があります。

# 基本的な使い方
`TypeScript`の基本的な使い方を紹介します。

## インストール
npmを利用してインストール
```shell:Shell
npm install -g typescript
```
バージョンを確認
```shell:Shell
tsc -v # => Version 4.X.X
```

## トランスコンパイル
コンパイルの設定ファイルを作成
```shell:Shell
tsc --init
```
トランスコンパイル（JSファイルを生成）
```shell:Shell
tsc index.ts # => index.jsが生成
```

## TypeScriptの変数
### 変数
変数宣言時に型を一緒に記述します
```typescript:index.ts
let sampleNum:  number = 1;
let sampleText: string = 'Hello';
```

### 関数
引数や戻り値にも型を記述します
戻り値の型は`( )`の後に追記します
```typescript:index.ts
function sum(a: number,b: number): number {
	return a * b ;
}

let answer: string = sum(5, 2);
console.log(answer); // => 10
```

```typescript:index.ts
// アロー関数

const sum = (a: number,b: number): number => {
	return a * b ;
}
```

### ジェネリック
引数の型を実行時に選択したい場合は、
ジェネリック`<T>`を使用します

```typescript:index.ts
const addColon = <T>(item: T) :string => {
return(':' + item);
}
cosole.log(addCoron<string>('サンプル')); => ':サンプル'
console.log(addCoron<number>(100)); => ':100'
```

### ユニオンタイプ
`|`で複数の型を許可することもできます
```typescript:index.ts
let tel: number | string; // 数値または文字列

tel = 08012345678;
tel = '080-1234-5678'; // 代入可能
```

### リスト
変数に代入許可する値をリスト`|`で指定できます
```typescript:index.ts
let weather: '晴れ' | 'くもり' | '雨';

weather = '晴れ';
weather = '嵐'; // => エラー
```

### 型推論
型を宣言しない場合は、自動的に型が予測され設定されます
再代入時に型不一致であればタイプエラーが発生します
```typescript:index.ts
let testText = '文字列'; // 推論で string になる
let testNumber = 100; // 推論で number になる

testText = 10; // エラー
testNumber = '文字列'; //エラー

// エラー回避のためには前述のユニオンタイプや「any」を指定
```

## TypeScriptのクラス
`JavaScript`でもES6からclass構文が利用できますが、`TypeScript`ではより厳密にクラスを定義できます。

### クラス
クラスの例を紹介します。
```typescript:index.ts
class Item {

  // プロパティの宣言
  public tax: number;
  private price: number;

  constructor(price: number, tax?:number) { // ?は省略可能な変数
    // taxが渡されなかった場合、10を代入
	if (tax) {
		this.tax  = tax;
	} else {
		this.tax = 10;
	}

	if (isFinite(price)) {
		this.price = price;
	} else {
		this.price = 0;
	}
  }

  public getTax(): number {
	return Math.round(this.price * (this.tax / 100));
  } 

let item: Item = new Item(200); // クラスを型のように宣言
console.log(item.tax); // => taxはpublicで宣言しているので取得可能
console.log(item.price); // => priceはprivateで定義しているのでエラー
console.log(item.getTax()); // => 200 * 10 / 100 = 20

```

### セッター・ゲッター
セッター・ゲッターの記述例を紹介します
> 変数前のアンダースコア`_`
> `private`な変数であることを明示します
```typescript:index.ts
class Book {
  private _name: string = '';

  set name(value: string) {
	if (value === '' ) {
		console.log('書籍名が指定されていません')
	} else {
		this._name = value;
	}
	get name(): string {
			return this._name;
	}
  }
}

let book: Book = new Book();
book.name = 'TypeScriptの超きほん'; // セッターで代入
console.log(book.name); // => 'TypeScriptの超きほん' ゲッターで取得
```
ゲッター・セッターを設定した際、トランスコンパイル後のJSがES5以降でないとAccessorsが使用できず、エラーになることがあります。

その場合は、コンパイル時にバージョンを指定する必要があります。

コンパイル実行時にオプションを利用
`tsc -t ES5 index.ts`

もしくは、

`tsconfig.json`を編集します。

### readonlyモード
「書き換え不可能・呼び出しのみ可能な変数」を定義したい場合、
`readonly`で設定することもできます。
```typescript:index.ts
readonly SAMPLE_TEXT: string = 'これはread only です'
```

# 補足
さいごまでお読みいただき、ありがとうございます！

この記事はプログラミング初心者であるわたしが、毎日の学習ログとして書きました。
ご質問やご意見、間違いのご指摘などがあれば、気軽にコメントください。

また、平日にもくもく作業したり質問しあえる仲間も募集しています。
ご興味がある方は[Twitter](https://twitter.com/yutaka_pg)などでご連絡くださいー！

これからもどうぞよろしくお願いします:rabbit: