TypeScriptの型定義まとめ


### <font color="#1e90ff">基本型</font>

#### <font color="green">プリミティブ型</font>
- `string`: 文字列
- `number`: 数値
- `boolean`: 真偽値
- `null`: null値
- `undefined`: 未定義値
- `symbol`: シンボル
- `bigint`: 大きな整数

```typescript:typescript
const name: string = "Alice";
const age: number = 30;
const isStudent: boolean = true;
const nothing: null = null;
const notDefined: undefined = undefined;
const uniqueId: symbol = Symbol("id");
const largeNumber: bigint = 9007199254740991n;
```


#### <font color="green">配列</font>
配列の型は、要素の型の後に `[]` を付けるか、`Array<型>` を使用します。

```typescript:typescript
const numbers: number[] = [1, 2, 3];
const strings: Array<string> = ["a", "b", "c"];
```


#### <font color="green">タプル</font>
タプルは固定長の配列で、各要素に異なる型を持たせることができます。

```typescript:typescript
const tuple: [string, number] = ["Alice", 30];
```


#### <font color="green">オブジェクト</font>
オブジェクトの型は、プロパティ名とその型を指定します。

```typescript:typescript
const person: { name: string; age: number } = {
  name: "Alice",
  age: 30,
};
```


### <font color="#1e90ff">複合型</font>

#### <font color="green">ユニオン型</font>
ユニオン型は、複数の型のいずれかを取ることができる型です。

```typescript:typescript
const id: string | number;
id = "abc";
id = 123;
```

#### <font color="green">インターセクション型</font>
インターセクション型は、複数の型を組み合わせた型です。

```typescript:typescript
type Person = { name: string };
type Employee = { employeeId: number };

const employee: Person & Employee = {
  name: "Alice",
  employeeId: 123,
};
```


### <font color="#1e90ff">特殊な型</font>

#### <font color="green">any</font>
`any` 型は、任意の型を許容します。型安全性が失われるため、使用は最小限に抑えるべきです。

```typescript:typescript
const anything: any = "Hello";
anything = 42;
```


#### <font color="green">unknown</font>
`unknown` 型は、`any` と似ていますが、より安全です。使用する前に型チェックが必要です。

```typescript:typescript
const unknownValue: unknown = "Hello";

if (typeof unknownValue === "string") {
  console.log(unknownValue.toUpperCase());
}
```


#### <font color="green">void</font>
`void` 型は、関数が値を返さないことを示します。

```typescript:typescript
function logMessage(message: string): void {
  console.log(message);
}
```


#### <font color="green">never</font>
`never` 型は、決して値を返さないことを示します。例として、常に例外を投げる関数があります。

```typescript:typescript
function error(message: string): never {
  throw new Error(message);
}
```

### <font color="#1e90ff">列挙型 (enum)</font>
列挙型は、名前付き定数の集合を定義します。
```typescript:typescript
enum Direction {
  Up,
  Down,
  Left,
  Right,
}
const direction: Direction = Direction.Up;
```



### <font color="#1e90ff">型エイリアス</font>
型エイリアスは、型に別名を付けることができます。

```typescript:typescript
type ID = string | number;
const userId: ID = "abc";
```


### <font color="#1e90ff">インターフェース</font>
インターフェースは、オブジェクトの構造を定義します。

```typescript:typescript
interface Person {
  name: string;
  age: number;
}

const person: Person = {
  name: "Alice",
  age: 30,
};
```


#### <font color="green">インターフェースの拡張</font>
インターフェースは他のインターフェースを拡張することができます。

```typescript:typescript
interface Person {
  name: string;
  age: number;
}

interface Employee extends Person {
  employeeId: number;
}

const employee: Employee = {
  name: "Alice",
  age: 30,
  employeeId: 123,
};
```


### <font color="#1e90ff">クラス</font>
クラスに型を付けることもできます。

```typescript:typescript
class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hello, my name is ${this.name}`;
  }
}

const person = new Person("Alice", 30);
```


### <font color="#1e90ff">ジェネリクス</font>
ジェネリクスは、型をパラメータ化することができます。これにより、再利用性の高いコードを書くことができます。

#### <font color="green">ジェネリック関数</font>
ジェネリック関数は、関数の引数や戻り値の型をパラメータ化します。

```typescript:typescript
function identity<T>(value: T): T {
  return value;
}

const result1 = identity<string>("Hello");
const result2 = identity<number>(123);
```


#### <font color="green">ジェネリックインターフェース</font>
ジェネリック型を持つインターフェースを定義することもできます。

```typescript:typescript
interface Box<T> {
  contents: T;
}

const stringBox: Box<string> = { contents: "Hello" };
const numberBox: Box<number> = { contents: 123 };
```


#### <font color="green">ジェネリッククラス</font>
ジェネリック型を持つクラスを定義することもできます。

```typescript:typescript
class Box<T> {
  contents: T;

  constructor(contents: T) {
    this.contents = contents;
  }

  getContents(): T {
    return this.contents;
  }
}

const stringBox = new Box<string>("Hello");
const numberBox = new Box<number>(123);
```


#### <font color="green">ジェネリック制約</font>
ジェネリクスに制約を付けることで、特定の型に限定することができます。

```typescript:typescript
interface Lengthwise {
  length: number;
}

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

logLength("Hello"); // OK
logLength([1, 2, 3]); // OK
// logLength(123); // エラー: 'number' 型に 'length' プロパティがないため
```


#### <font color="green">デフォルト型パラメータ</font>
ジェネリクスにデフォルトの型パラメータを設定することができます。

```typescript:typescript
function createArray<T = string>(length: number, value: T): T[] {
  return Array(length).fill(value);
}

const stringArray = createArray(3, "Hello"); // string[]
const numberArray = createArray<number>(3, 123); // number[]
```


#### <font color="green">ジェネリックユーティリティ型</font>
TypeScriptには、ジェネリクスを利用した便利なユーティリティ型がいくつか用意されています。

##### <font color="green">`Partial<T>`</font>
すべてのプロパティをオプショナルにします。

```typescript:typescript
interface Person {
  name: string;
  age: number;
}

const partialPerson: Partial<Person> = {
  name: "Alice",
};
```


##### <font color="green">`Required<T>`</font>
すべてのプロパティを必須にします。

```typescript:typescript
interface Person {
  name?: string;
  age?: number;
}

const requiredPerson: Required<Person> = {
  name: "Alice",
  age: 30,
};
```


##### <font color="green">`Readonly<T>`</font>
すべてのプロパティを読み取り専用にします。

```typescript:typescript
interface Person {
  name: string;
  age: number;
}

const readonlyPerson: Readonly<Person> = {
  name: "Alice",
  age: 30,
};

// readonlyPerson.age = 31; // エラー: 'age' は読み取り専用プロパティです
```


##### <font color="green">`Record<K, T>`</font>
特定のキーと値の型を持つオブジェクトを作成します。

```typescript:typescript
type Role = "admin" | "user" | "guest";

const roles: Record<Role, string> = {
  admin: "Administrator",
  user: "Regular User",
  guest: "Guest User",
};
```


##### <font color="green">`Pick<T, K>`</font>
特定のプロパティだけを持つ型を作成します。

```typescript:typescript
interface Person {
  name: string;
  age: number;
  address: string;
}

const personNameAndAge: Pick<Person, "name" | "age"> = {
  name: "Alice",
  age: 30,
};
```


##### <font color="green">`Omit<T, K>`</font>
特定のプロパティを除外した型を作成します。

```typescript:typescript
interface Person {
  name: string;
  age: number;
  address: string;
}

const personWithoutAddress: Omit<Person, "address"> = {
  name: "Alice",
  age: 30,
};
```

### <font color="#1e90ff">型ガード</font>
型ガードは、特定の型であることを確認するための方法です。
```typescript:typescript
function isString(value: unknown): value is string {
  return typeof value === "string";
}
const value: unknown = "Hello";
if (isString(value)) {
  console.log(value.toUpperCase()); // 型が string であることが保証される
}
```

### <font color="#1e90ff">条件付き型</font>
条件付き型は、条件に基づいて型を選択します。
```typescript:typescript
type IsString<T> = T extends string ? "string" : "not string";
type A = IsString<string>; // "string"
type B = IsString<number>; // "not string"
```