# TypeScript 빠른 참조

*타입, 인터페이스, 제네릭, 유틸리티 타입*

> Source: TypeScript Documentation (typescriptlang.org) · MIT

## 기본 타입

### 원시 타입

```
let name: string = "Alice";
let age: number = 25;
let active: boolean = true;
let data: null = null;
let x: undefined = undefined;
```

### 특수 타입

| Command | Description |
|---------|-------------|
| `any` | 타입 검사 해제 |
| `unknown` | 타입 안전한 `any` (사용 전 좁혀야 함) |
| `void` | 반환 값 없음 |
| `never` | 함수가 절대 반환하지 않음 (throw / 무한 루프) |
| `object` | 원시 타입이 아닌 모든 타입 |

## 배열 및 튜플

### 배열

```
let nums: number[] = [1, 2, 3];
let names: Array<string> = ["a", "b"];
let matrix: number[][] = [[1, 2], [3, 4]];
```

### 튜플

```
let pair: [string, number] = ["age", 25];
let rgb: [number, number, number] = [255, 0, 0];

// Named tuples (labels for readability)
type Point = [x: number, y: number];
```

## 인터페이스

### 정의 및 사용

```
interface User {
  name: string;
  age: number;
  email?: string;        // optional
  readonly id: number;   // immutable
}

const user: User = { name: "Alice", age: 25, id: 1 };
```

### 인터페이스 확장

```
interface Employee extends User {
  role: string;
  department: string;
}
```

### 인덱스 시그니처

```
interface StringMap {
  [key: string]: string;
}
const env: StringMap = { NODE_ENV: "prod" };
```

## 타입 별칭

```
type ID = string | number;
type Point = { x: number; y: number };
type Callback = (data: string) => void;
```

### interface vs type

| Command | Description |
|---------|-------------|
| `interface` | `extends`로 확장 가능, 선언 병합 |
| `type` | 유니온, 교차, 매핑된 타입, 튜플 |

## 유니온 및 교차

### 유니온 타입

```
type Status = "loading" | "success" | "error";
type ID = string | number;

function print(val: string | number) {
  if (typeof val === "string") {
    console.log(val.toUpperCase());
  }
}
```

### 교차 타입

```
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
// Person has both name and age
```

### 판별 유니온

```
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "rect"; w: number; h: number };

function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.radius ** 2;
    case "rect":   return s.w * s.h;
  }
}
```

## 함수

### 타입이 지정된 매개변수 및 반환

```
function add(a: number, b: number): number {
  return a + b;
}

// Arrow function
const greet = (name: string): string =>
  `Hello, ${name}!`;

// Optional & default params
function log(msg: string, level?: string): void {}
function log(msg: string, level = "info"): void {}
```

### 함수 오버로드

```
function parse(input: string): number;
function parse(input: number): string;
function parse(input: string | number) {
  return typeof input === "string"
    ? parseInt(input)
    : input.toString();
}
```

### 나머지 매개변수

```
function sum(...nums: number[]): number {
  return nums.reduce((a, b) => a + b, 0);
}
```

## 제네릭

### 제네릭 함수

```
function identity<T>(value: T): T {
  return value;
}
identity<string>("hello"); // explicit
identity(42);              // inferred: number
```

### 제네릭 인터페이스 및 제약

```
interface Box<T> {
  value: T;
}
const box: Box<number> = { value: 42 };

// Constraints
function getLen<T extends { length: number }>(
  item: T
): number {
  return item.length;
}
```

## 열거형

```
enum Direction { Up, Down, Left, Right }
let d: Direction = Direction.Up; // 0

enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE",
}
let s: Status = Status.Active; // "ACTIVE"

// const enum (inlined at compile time)
const enum Color { Red, Green, Blue }
```

## 타입 가드

### 내장 가드

```
// typeof
if (typeof x === "string") { /* x: string */ }

// instanceof
if (err instanceof Error) { /* err: Error */ }

// in
if ("name" in obj) { /* obj has name */ }
```

### 커스텀 타입 가드

```
function isString(val: unknown): val is string {
  return typeof val === "string";
}

if (isString(input)) {
  input.toUpperCase(); // narrowed to string
}
```

### 단언 함수

```
function assertDefined<T>(
  val: T | null
): asserts val is T {
  if (val === null) throw new Error("null");
}
```

## 유틸리티 타입

| Command | Description |
|---------|-------------|
| `Partial<T>` | 모든 속성을 선택적으로 |
| `Required<T>` | 모든 속성을 필수로 |
| `Readonly<T>` | 모든 속성을 읽기 전용으로 |
| `Pick<T, K>` | T에서 K 속성 선택 |
| `Omit<T, K>` | T에서 K 속성 제거 |
| `Record<K, V>` | 키 K와 값 V를 가진 객체 |
| `Exclude<T, U>` | T에서 U에 없는 타입 |
| `Extract<T, U>` | T에서 U에도 있는 타입 |
| `NonNullable<T>` | T에서 null과 undefined 제거 |
| `ReturnType<T>` | 함수 T의 반환 타입 |
| `Parameters<T>` | 함수 T의 매개변수 타입 |
| `Awaited<T>` | Promise 타입 언래핑 |

### 유틸리티 타입 예제

```
interface User { name: string; age: number; email: string }

type UserPreview = Pick<User, "name" | "email">;
type UserUpdate = Partial<User>;
type UserMap = Record<string, User>;
type CreateUser = Omit<User, "id">;
```
