TypeScriptの基本まとめ

# 初めに
TypeScriptの基本の書き方についてまとめます。
実際のコードは以下のオンラインエディタなどで動作確認してみてください。

https://stackblitz.com/

# オンラインエディタの使い方
URLをクリックすると以下のような画面に遷移すると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/ce9ee7b5-a4ff-5ee1-c3fd-8457245fc173.png)
今回はTypeScriptを使用するので右上のTypeScriptをクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/e56baf35-b9e7-ae5b-c7d0-cb2dc0d5fabb.png)
クリックすると以下のよ画面に遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663952/c01ec610-c8fe-f7ec-7520-fe1974556b27.png)
基本的にはVSCodeと同じように使用できます。

# 目次
|No|概要|
|---|---|
|No.1|[データ型](#データ型)|
|No.2|[スプレッド演算子](#スプレッド演算子)|
|No.3|[テンプレートリテラル](#テンプレートリテラル)|
|No.4|[基本の関数](#基本の関数)|
|No.5|[アロー関数](#アロー関数)|
|No.6|[クラスの基本](#クラスの基本)|
|No.7|[アクセッサ](#アクセッサ)|
|No.8|[継承](#継承)|
|No.9|[インターフェース](#インターフェース)|
|No.10|[ジェネリクス](#ジェネリクス)|

# データ型
以下は基本的なデータ型の宣言方法です。
```:#データ型の宣言方法
var 変数名:型名;
let 変数名:型名;
const 変数名:型名;
```
型にはいかのような種類がございます。
|型種類|
|---|
|[文字列型](#文字列型)|
|[数値型](#数値型)|
|[真偽値型](#真偽値型)|
|[配列型](#配列型)|
|[タプル型](#タプル型)|
|[オブジェクト型](#オブジェクト型)|
|[Union型](#union型)|
|[enum型](#enum型)|
|[Element型](#element型)|
|[any型](#any型)|

上記以外にも色々な型がございます。
## 文字列型
文字列型で宣言し、「__Hello, World__」を表示するプログラムです。
```#indnex.ts
let str: string = 'Hello, World';
console.log(str);
```
上記の実行結果です。
```#実行結果
Hello, World
```
## 数値型
数値型で宣言し、「__10 + 20__」の計算結果を表示するプログラムです。
```#indnex.ts
let num1: number = 10;
let num2: number = 20;
let sum: number = num1 + num2;
console.log(sum);
```
上記の実行結果です。
```#実行結果
30
```
## 真偽値型
真偽値型で宣言し、「__真__」か「__偽__」を判定するプログラムです。
```#indnex.ts
let flg: boolean = true;
if (flg) {
  console.log('真');
} else {
  console.log('偽');
}
```
上記の実行結果です。
```#実行結果
真
```
## 配列型
配列型で宣言し、任意の値を配列型の変数に格納して値を表示するプログラムです。
配列の型は __パイプ区切り(|)__ で複数指定できます。
```#indnex.ts
let array: (string | number | boolean)[] = [
  'Hello',
  10,
  true,
  false,
  20,
  'World',
];
console.log(array);
```
上記の実行結果です。
```#実行結果
["Hello", 10, true, false, 20, "World"]
0: "Hello"
1: 10
2: true
3: false
4: 20
5: "World"
```
## タプル型
タプル型で宣言し、任意の値をタプル型の変数に格納して値を表示するプログラムです。
タプル型と配列型の違いは __それぞれのインデックスごとに型を指定するかどうか__ の違いがります。
```#indnex.ts
let tuple: [string, number, boolean] = ['Hello', 10, true];
console.log(tuple);
```
上記の実行結果です。
```#実行結果
["Hello", 10, true]
0: "Hello"
1: 10
2: true
```
## オブジェクト型
keyが数値型、valueが文字列型であるオブジェクト型を宣言し、任意の値を変数に格納して値を表示するプログラムです。
```#indnex.ts
let obj: { [key: number]: string } = {
  1: '佐藤',
  2: '鈴木',
  3: '高橋',
  4: '田中',
  5: '伊藤',
};
console.log(obj);
```
上記の実行結果です。
```#実行結果
{1: "佐藤", 2: "鈴木", 3: "高橋", 4: "田中"…}
1: "佐藤"
2: "鈴木"
3: "高橋"
4: "田中"
5: "伊藤"
__proto__: Object
```
オブジェクト型で宣言し、任意の値をオブジェクト型の変数に格納して値を表示するプログラムです。
```#indnex.ts
let obj: object = [
  { id: 1, content: 'Hello' },
  { flg: true, result: 'OK' },
];
console.log(obj);
```
上記の実行結果です。
```#実行結果
[Object, Object]
0: Object
content: "Hello"
id: 1
__proto__: Object
1: Object
flg: true
result: "OK"
__proto__: Object
```
インターフェースを使用してオブジェクト型の指定した方法で任意の値を表示するプログラムです。
```#indnex.ts
interface Person {
  name: string;
  gender: string;
  age: number;
}
let person: Person = {
  name: 'Tarou',
  gender: 'Male',
  age: 10,
};
console.log(person);
```
上記の実行結果です。
```#実行結果
{name: "Tarou", gender: "Male", age: 10}
age: 10
gender: "Male"
name: "Tarou"
__proto__: Object
```
オブジェクト型は他にも色々な書き方がございます。
## Union型
Union型で宣言し、任意の値をUnion型の変数に格納して値を表示するプログラムです。
Union型は __パイプ区切り(|)__ で複数指定できます。
Union型は複数の型の値を変数に格納できる宣言方法です。
```:#indnex.ts
let union: string | number | boolean;
union = 'Hello, World';
console.log(union);
union = 10;
console.log(union);
union = true;
console.log(union);
```
上記の実行結果です。
```#実行結果
Hello, World
10
true
```
## enum型
enum型で宣言し、その値を表示するプログラムです。(名前のみ定義)
```:#indnex.ts
enum Fruit {
  APPLE,
  ORANGE,
  PEACH,
}
console.log(Fruit);
console.log(Fruit.APPLE);
```
上記の実行結果です。
```#実行結果
{0: "APPLE", 1: "ORANGE", 2: "PEACH"}
0: "APPLE"
1: "ORANGE"
2: "PEACH"
APPLE: 0
ORANGE: 1
PEACH: 2
__proto__: Object
0
```
enum型で宣言し、その値を表示するプログラムです。(名前と値の両方定義)
```:#indnex.ts
enum ErrorCode {
  AccessDenied = 403,
  InvalidArgument = 400,
  NoSuchBucket = 404,
  InternalError = 500,
}
console.log(ErrorCode);
console.log(ErrorCode.AccessDenied);
```
上記の実行結果です。
```#実行結果
{400: "InvalidArgument", 403: "AccessDenied", 404: "NoSuchBucket", 500: "InternalError"…}
400: "InvalidArgument"
403: "AccessDenied"
404: "NoSuchBucket"
500: "InternalError"
AccessDenied: 403
InternalError: 500
InvalidArgument: 400
NoSuchBucket: 404
__proto__: Object
403
```
## Element型
Element型で宣言し、任意のHtmlタグの値をElement型の変数に格納して値を表示するプログラムです。
```:#indnex.html
<h1>Test</h1>
```
```:#indnex.ts
let element: Element = document.querySelector('h1');
console.log(element);
console.log(element.innerHTML);

```
上記の実行結果です。
```#実行結果
HTMLHeadingElement {tagName: "h1", attributes: {…}, innerHTML: "Test", nodeType: 1…}
attributes: Object
innerHTML: "Test"
nodeType: 1
tagName: "h1"
__proto__: HTMLHeadingElement
Test
```
## any型
any型で宣言し、任意の値をany型の変数に格納して値を表示するプログラムです。
any型はどんな型の値でも入れられる型です。
```:#indnex.ts
let allType: any;
allType = 10;
console.log(allType);
allType = 'Test';
console.log(allType);
allType = true;
console.log(allType);
allType = ['a', 10, true];
console.log(allType);
allType = { name: 'Tarou', gender: 10 };
console.log(allType);
```
上記の実行結果です。
```#実行結果.
10
Test
true
["a", 10, true]
0: "a"
1: 10
2: true
{name: "Tarou", gender: 10}
gender: 10
name: "Tarou"
__proto__: Object
```
# スプレッド演算子
スプレッド演算子は、配列またはオブジェクトの要素を展開することができます。
以下は、少年の名前の一覧(boys)と少女の名前の一覧(girls)を子供の一覧(children)にまとめて、その一覧を表示したプログラムです。
```:#index.ts
let boys = ['Tarou', 'Jirou', 'Saburou'];
let girls = ['Yukiko', 'Hanako', 'Tukiko'];
let children = [...boys, ...girls];
console.log(children);
console.log(...children);
```
上記の実行結果です。
```:#実行結果
["Tarou", "Jirou", "Saburou", "Yukiko", "Hanako", "Tukiko"]
0: "Tarou"
1: "Jirou"
2: "Saburou"
3: "Yukiko"
4: "Hanako"
5: "Tukiko"
Tarou Jirou Saburou Yukiko Hanako Tukiko
```
# テンプレートリテラル
テンプレートリテラルは、シングルクォート(')またはダブルクォート(")の代わりに __バッククォート(`)__ を使う文字列です。
テンプレートリテラルには以下の特徴があります
|特徴|
|---|
|[文字列展開](#文字列展開)|
|[複数行の文字列](#複数行の文字列)|
|[タグ付きテンプレート](#タグ付きテンプレート)|

## 文字列展開
文字列展開は、任意の文字列の変数をテンプレートリテラルを使用した文字列内に「__${任意の文字列の変数}__」の形で埋め込むことで文字列を動的に変更できる方法です。
任意の文字列の変数はシングルクォート(')またはダブルクォート(")で大丈夫です。
```:#index.ts
let addWord = 'Pen';
let sentence = `This is a ${addWord}.`;
console.log(sentence);
```
上記の実行結果です。
```:#実行結果
This is a Pen.
```
## 複数行の文字列
テンプレートリテラルは、文字列内に改行を入れた場合に改行を入れることができます。
```:#index.ts
let templete = `こんにちは。
ようこそ。
`;
console.log(templete);
```
上記の実行結果です。
```:#実行結果
こんにちは。
ようこそ。
```
## タグ付きテンプレート
タグ付きテンプレートは、テンプレートリテラルのタグ名の関数を処理を事前に入れることができます。
追加する文字列が空の場合は何も表示させず、何か文字がある場合はテンプレートリテラル内容を表示させるプログラムです。、
```:#index.ts
let addWord = 'Pen';
let sentence = tagTemplate`This is a ${addWord}.`;
console.log(sentence);

function tagTemplate(template: TemplateStringsArray, ...words: string[]) {
  /* 追加する単語が空の場合は何も返さない*/
  if (!words?.[0]) return '';
  let result = template[0].concat(words[0], template[1]);
  return result;
}
```
上記の実行結果です。
```:#実行結果
This is a Pen.
```
# 基本の関数
関数の基本的な定義方法です。
```:#関数の定義方法
function 関数名(引数名1:引数名1の型,引数名2:引数名2の型...):戻り値の型{
   // 任意の処理
   return 戻り値
}
```
任意の2つ値の足し算を行う関数のプログラムです。
```:#index.ts
function calculation(num1: number, num2: number): number {
  return num1 + num2;
}

let sum: number = calculation(10, 20);
console.log(sum);
```
上記の実行結果です。
```:#実行結果
30
```
# アロー関数
アロー関数の定義方法です。
```:#アロー関数の定義方法
(引数名1:引数名1の型,引数名2:引数名2の型...):戻り値の型 =>{
   // 任意の処理
   return 戻り値
}
```
任意の2つ値の足し算を行う関数のプログラムです。
```:#index.ts
let sum = (num1: number, num2: number): number => {
  return num1 + num2;
};
console.log(sum(10, 20));
```
上記の実行結果です。
```:#実行結果
30
```
# クラスの基本
```:クラスの定義方法
class Calculation {
  constructor(アクセス修飾子 引数名:型...) {}

  アクセス修飾子 関数名(): 戻り値 {
    return 戻り値;
  }
...
}
```
任意の2つの値を足し算する機能と引き算する機能をもつクラスのプログラムです。
```:#index.ts
class Calculation {
  constructor(private num1: number, private num2: number) {}

  public calculationSum(): number {
    return this.num1 + this.num2;
  }

  public calculationSub() {
    return this.num1 - this.num2;
  }
}

let calc = new Calculation(10, 5);
console.log(calc.calculationSum());
console.log(calc.calculationSub());
```
上記の実行結果です。
```:#実行結果
15
5
```

# アクセッサ
アクセッサ(getter,setter)の定義方法です。
```:#アクセッサ(getter,setter)の定義方法
class クラス名 {
  private _アクセッサ名: アクセッサ名の型;

  set アクセッサ名(セットする引数名: セットする引数名の型) {
    this._アクセッサ名 = セットする引数名;
  }
  get アクセッサ名() {
    return this._アクセッサ名;
  }
}

let 変数名　= new クラス名();
変数名.アクセッサ名 = セットする値
変数名.アクセッサ名 // セットされた値の取得
```
ユーザに名前と年齢を設定し、その内容を表示するプログラムです。
```:#index.ts
class User {
  private _name: string;
  private _age: number;

  get name() {
    return this._name;
  }

  set name(name: string) {
    this._name = name;
  }
 
  get age() {
    return this._age;
  }
 
  set age(age: number) {
    this._age = age;
  }
}

let user = new User();
user.name = 'Tarou';
user.age = 10;
console.log(user);
console.log(user.name);
console.log(user.age);
```
上記の実行結果です。
```:#実行結果
User {_name: "Tarou", _age: 10}
_age: 10
_name: "Tarou"
__proto__: User
Tarou
10
```
# 継承
継承の定義方法です。
```:#継承の定義方法
class 子クラス名 extends 親クラス名{
 
}
```
共通情報としてID(id)と名前(name)があり、独自に性別と名前を持つユーザ情報の内容を表示するプログラムです。
```:#index.ts
class CommonInfomation {
  private _id: string;
  private _name: string;

  get id() {
    return this._id;
  }

  set id(id: string) {
    this._id = id;
  }

  get name() {
    return this._name;
  }

  set name(name: string) {
    this._name = name;
  }
}

class User extends CommonInfomation {
  private _gender: string;
  private _age: number;

  get gender() {
    return this._gender;
  }
  set gender(gender: string) {
    this._gender = gender;
  }

  get age() {
    return this._age;
  }
  set age(age: number) {
    this._age = age;
  }
}

let user = new User();
user.id = '001';
user.name = 'Tarou';
user.gender = '男';
user.age = 10;

console.log(user);
```
上記の実行結果です。
```:#実行結果
User {_id: "001", _name: "Tarou", _gender: "男", _age: 10…}
_age: 10
_gender: "男"
_id: "001"
_name: "Tarou"
__proto__: User
```

# インターフェース
インターフェースの定義方法のです。
```:インターフェースの定義方法
interface インターフェース名{
  変数名:変数名の型;
  関数名():戻り値の型;
  ...
}
```
任意の2つの値を足し算する機能と引き算する機能をもつクラスのプログラムです。
```:#index.ts
interface CalculationImpl {
  num1: number;
  num2: number;
  calculationSum(): number;
  calculationSub(): number;
}

class Calculation implements CalculationImpl {
  num1: number;
  num2: number;
  constructor(num1: number, num2: number) {
    this.num1 = num1;
    this.num2 = num2;
  }
  calculationSum(): number {
    return this.num1 + this.num2;
  }
  calculationSub(): number {
    return this.num1 - this.num2;
  }
}

let calc = new Calculation(10, 5);
console.log(calc.calculationSum());
console.log(calc.calculationSub());
```
上記の実行結果です。
```:#実行結果
15
5
```
# ジェネリクス
ユーザ情報(UserTable)と商品情報(ItemTable)をテーブルクラス(Table)にセットして内容を表示するプログラムです。
```:#index.ts
/* テーブルクラス */
class Table<T> {
  data: T;
  getData(): T {
    return this.data;
  }
}

/* UserTableとItemTableの共通情報クラス */
class CommonInfomation {
  private _id: string;
  private _name: string;
  get id() {
    return this._id;
  }

  set id(id: string) {
    this._id = id;
  }

  get name() {
    return this._name;
  }

  set name(name: string) {
    this._name = name;
  }
}

/* UserTableクラス */
class UserTable extends CommonInfomation {
  private _gender: string;
  private _age: number;

  get gender() {
    return this._gender;
  }

  set gender(gender: string) {
    this._gender = gender;
  }

  get age() {
    return this._age;
  }

  set age(age: number) {
    this._age = age;
  }
}

/* ItemTableクラス */
class ItemTable extends CommonInfomation {
  private _maker: string;
  get maker() {
    return this._maker;
  }

  set maker(maker: string) {
    this._maker = maker;
  }
}

/* UserTableクラスにデータをセット */
let ut = new UserTable();
ut.id = '001';
ut.name = 'Tarou';
ut.gender = '男';
ut.age = 10;

/* ItemTableクラスにデータをセット */
let it = new ItemTable();
it.id = '10001';
it.name = '牛乳';
it.maker = '森永';

/* UserTableの内容を表示 */
let tableUT = new Table<UserTable>();
tableUT.data = ut;
console.log(tableUT.getData());

/* ItemTableの内容を表示 */
let tableIT = new Table<ItemTable>();
tableIT.data = it;
console.log(tableIT.getData());
```
上記の実行結果です。
```:#実行結果
UserTable {_id: "001", _name: "Tarou", _gender: "男", _age: 10…}
_age: 10
_gender: "男"
_id: "001"
_name: "Tarou"
__proto__: UserTable
ItemTable {_id: "10001", _name: "牛乳", _maker: "森永"}
_id: "10001"
_maker: "森永"
_name: "牛乳"
__proto__: ItemTable
```