---
id: wiki-2026-0508-typescript-type-safety
title: TypeScript Type Safety
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Type Safety, TS Safety, strict mode]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-safety, frontend, quality]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: TypeScript
  framework: TypeScript 5.7
---

# TypeScript Type Safety

## 매 한 줄
> **"매 compile-time 에서 매 runtime 오류를 차단하는 매 contract enforcement"**. 매 단순 typing 이 아니라 매 strict flag, 매 narrowing, 매 boundary validation 의 매 종합 practice. 매 2026 production code 의 매 default expectation.

## 매 핵심

### 매 strict mode
- `strict: true` — 매 모든 strict flag 활성화.
- `noUncheckedIndexedAccess: true` — 매 array / index access 에 매 `undefined` 추가.
- `exactOptionalPropertyTypes: true` — 매 `?` 와 `undefined` 구분.

### 매 Narrowing
- `typeof`, `instanceof`, `in`, equality.
- User-defined type guard: `x is Foo`.
- `assertion function`: `asserts x is Foo`.

### 매 응용
1. API boundary — Zod / Valibot validation.
2. Error handling — `Result<T, E>` instead of throw.
3. Null safety — strict null checks.

## 💻 패턴

### Type guard
```typescript
function isString(x: unknown): x is string {
  return typeof x === 'string';
}
function process(input: unknown) {
  if (isString(input)) input.toUpperCase(); // narrowed to string
}
```

### Assertion function
```typescript
function assertDefined<T>(x: T | undefined): asserts x is T {
  if (x === undefined) throw new Error('undefined');
}
const u: User | undefined = find();
assertDefined(u);
u.name; // ok
```

### Boundary validation with Zod
```typescript
import { z } from 'zod';
const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email()
});
type User = z.infer<typeof UserSchema>;

async function fetchUser(id: string): Promise<User> {
  const res = await fetch(`/api/users/${id}`).then(r => r.json());
  return UserSchema.parse(res); // throws on invalid
}
```

### Result type instead of throw
```typescript
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

async function safeFetch<T>(url: string): Promise<Result<T>> {
  try {
    const r = await fetch(url);
    return { ok: true, value: await r.json() };
  } catch (e) {
    return { ok: false, error: e as Error };
  }
}
```

### Branded types for ID safety
```typescript
type UserId = string & { readonly __brand: 'UserId' };
type PostId = string & { readonly __brand: 'PostId' };

function fetchUser(id: UserId) { /* ... */ }
const pid = 'p1' as PostId;
// fetchUser(pid); // compile error — can't mix IDs
```

### tsconfig strict baseline
```jsonc
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "noFallthroughCasesInSwitch": true
  }
}
```

## 매 결정 기준
| 상황 | 도구 |
|---|---|
| 외부 JSON 입력 | Zod / Valibot |
| ID 혼동 방지 | Branded types |
| nullable handling | strict + narrowing |
| async error | `Result` or neverthrow |

**기본값**: `strict: true` + Zod boundary + Result for async.

## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)]]
- 변형: [[Branded-Types-for-Nominal-Typing]] · [[Discriminated Union]]
- 응용: [[Zod]] · [[neverthrow]]
- Adjacent: [[Error Handling]] · [[API Design]]

## 🤖 LLM 활용
**언제**: 매 schema → type 생성, 매 strict refactor.
**언제 X**: 매 runtime validation 빠뜨리지 X — 매 LLM 이 type 만 추가하고 매 boundary check 누락하는 경우 흔함.

## ❌ 안티패턴
- **`as` cast**: 매 진짜 narrowing 우회 — 매 type 시스템 무력화.
- **`any` import**: 매 외부 lib type 부족하다고 매 `any` 처리.
- **Type-only no runtime**: 매 API 응답 타입 선언만 하고 매 validate X.

## 🧪 검증 / 중복
- Verified (TypeScript strict mode docs, Total TypeScript principles).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — strict + boundary + Result 정리 |
