TypeScriptの入門コース: 汗かいて学ぶTypeScript

## はじめに

TypeScriptは、JavaScriptに静的型付けを追加した強力なプログラミング言語です。本記事では、TypeScriptの基本的な概念と使い方を、サンプルコードを交えながら解説していきます。

## 1. TypeScriptとは

TypeScriptは、Microsoftが開発したオープンソースの言語で、JavaScriptのスーパーセットです。つまり、既存のJavaScriptコードはそのままTypeScriptとして動作します。

TypeScriptの主な特徴:

- 静的型付け
- クラスベースのオブジェクト指向プログラミング
- モジュールシステム
- 最新のECMAScript機能のサポート

## 2. 開発環境のセットアップ

TypeScriptを使い始めるには、Node.jsとnpmをインストールする必要があります。

1. Node.jsをインストール: https://nodejs.org/
2. TypeScriptをグローバルにインストール:

```bash
npm install -g typescript
```

3. プロジェクトフォルダを作成し、初期化:

```bash
mkdir typescript-intro
cd typescript-intro
npm init -y
```

4. TypeScriptの設定ファイル（tsconfig.json）を作成:

```bash
tsc --init
```

## 3. 基本的な型

TypeScriptでは、変数や関数の引数、戻り値に型を指定できます。

```typescript
// 基本的な型
let message: string = "こんにちは、TypeScript!";
let count: number = 10;
let isActive: boolean = true;

// 配列
let numbers: number[] = [1, 2, 3, 4, 5];
let fruits: Array<string> = ["りんご", "バナナ", "オレンジ"];

// タプル
let person: [string, number] = ["田中", 30];

// enum
enum Color {
  Red,
  Green,
  Blue
}
let favoriteColor: Color = Color.Blue;

// any
let dynamicValue: any = 4;
dynamicValue = "文字列も代入可能";

// void（関数の戻り値がない場合）
function logMessage(message: string): void {
  console.log(message);
}

// null と undefined
let n: null = null;
let u: undefined = undefined;

// オブジェクト
let user: { name: string; age: number } = {
  name: "佐藤",
  age: 25
};
```

## 4. 関数

TypeScriptでは、関数の引数と戻り値に型を指定できます。

```typescript
// 基本的な関数
function add(a: number, b: number): number {
  return a + b;
}

// アロー関数
const multiply = (a: number, b: number): number => a * b;

// オプショナルパラメータ
function greet(name: string, greeting?: string): string {
  if (greeting) {
    return `${greeting}, ${name}!`;
  }
  return `こんにちは、${name}!`;
}

// デフォルトパラメータ
function createUser(name: string, age: number = 20): { name: string; age: number } {
  return { name, age };
}

// レストパラメータ
function sum(...numbers: number[]): number {
  return numbers.reduce((total, num) => total + num, 0);
}

// 関数オーバーロード
function padding(all: number): { top: number; right: number; bottom: number; left: number };
function padding(topAndBottom: number, leftAndRight: number): { top: number; right: number; bottom: number; left: number };
function padding(top: number, right: number, bottom: number, left: number): { top: number; right: number; bottom: number; left: number };
function padding(a: number, b?: number, c?: number, d?: number): { top: number; right: number; bottom: number; left: number } {
  if (b === undefined && c === undefined && d === undefined) {
    b = c = d = a;
  } else if (c === undefined && d === undefined) {
    c = a;
    d = b;
  }
  return {
    top: a,
    right: b,
    bottom: c,
    left: d
  };
}
```

## 5. インターフェースとクラス

インターフェースとクラスを使用して、より複雑な型を定義できます。

```typescript
// インターフェース
interface Vehicle {
  brand: string;
  year: number;
  start(): void;
}

// クラス
class Car implements Vehicle {
  constructor(public brand: string, public year: number) {}

  start() {
    console.log(`${this.brand}の車が始動しました。`);
  }

  honk() {
    console.log("ビービー！");
  }
}

// 継承
class ElectricCar extends Car {
  constructor(brand: string, year: number, public batteryCapacity: number) {
    super(brand, year);
  }

  charge() {
    console.log(`${this.brand}の電気自動車を充電中...`);
  }
}

// 使用例
const myCar = new Car("トヨタ", 2022);
myCar.start(); // 出力: トヨタの車が始動しました。

const myTesla = new ElectricCar("テスラ", 2023, 100);
myTesla.start(); // 出力: テスラの車が始動しました。
myTesla.charge(); // 出力: テスラの電気自動車を充電中...
```

## 6. ジェネリクス

ジェネリクスを使用すると、型を引数として受け取る汎用的なコードを書くことができます。

```typescript
// ジェネリック関数
function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("こんにちは");
let output2 = identity(42); // 型推論により、numberと判断される

// ジェネリッククラス
class Box<T> {
  private content: T;

  constructor(value: T) {
    this.content = value;
  }

  getValue(): T {
    return this.content;
  }
}

let stringBox = new Box("TypeScript");
let numberBox = new Box(100);

console.log(stringBox.getValue()); // 出力: TypeScript
console.log(numberBox.getValue()); // 出力: 100

// ジェネリック制約
interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): void {
  console.log(arg.length);
}

logLength("こんにちは"); // 出力: 5
logLength([1, 2, 3]); // 出力: 3
// logLength(3); // エラー: numberには'length'プロパティがありません
```

## 7. モジュール

TypeScriptでは、コードを複数のファイルに分割し、モジュールとして管理できます。

```typescript
// math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function subtract(a: number, b: number): number {
  return a - b;
}

// main.ts
import { add, subtract } from "./math";

console.log(add(5, 3)); // 出力: 8
console.log(subtract(10, 4)); // 出力: 6
```

## まとめ

この記事では、TypeScriptの基本的な概念と使い方を紹介しました。TypeScriptを使うことで、JavaScriptに静的型チェックを追加し、より安全で保守性の高いコードを書くことができます。

TypeScriptの学習を続けることで、より高度な機能や設計パターンを習得し、大規模なアプリケーション開発にも対応できるようになります。ぜひ、実際にコードを書いて練習してみてください。