C.W.K.
Stream
Lesson 04 of 05 · published

`as const`: Literal 세계 freeze

~10 min · arrays-tuples, as-const, literal-types, readonly

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"`as const` 는 한 keyword 의 3 기능: readonly, narrow, tuple. 값이 정확히 자기 자신이길 원할 때마다 써."

`as const` 가 뭐 함

`as const` assertion 이 적용된 어떤 거든 3가지 동시에 함:

  1. 모든 값이 widening 된 타입에서 literal 타입으로 narrow. string 대신 'red'. number 대신 42. boolean 대신 true.
  2. 모든 property 가 readonly 됨. Object property 가 `readonly` modifier 얻고; 배열이 readonly 배열 됨.
  3. 배열 literal 이 단일 element 타입의 (가변 길이) 배열 대신 (고정 길이, 위치별 타입의) tuple 됨.

결합 효과: 값의 타입이 정확히 자기 모양 됨, widening 없이, mutation 없이, 유연성 없이. "이 정확한 거 진짜로 의미" 의 가장 강한 형태.

손 뻗을 때

1. 고정 configuration object. const ROUTES = { CHAT: '/chat', LOGIN: '/login' } as const — 모든 값이 literal string 타입 되고, object 가 mutate 못 됨. 나중에 함수 parameter 를 route: typeof ROUTES[keyof typeof ROUTES] 로 타입 붙이면, 실제 route 문자열의 literal union 얻어.

2. 고정 상수 list. const COLORS = ['red', 'green', 'blue'] as const — 배열이 `readonly ['red', 'green', 'blue']`, literal 타입의 tuple. typeof COLORS[number] 가 literal union 'red' | 'green' | 'blue' 줘.

3. Literal-union parameter 가진 함수에 전달되는 object literal. `as const` 없으면, { method: 'POST' } 가 `{ method: string }` 추론, `{ method: 'GET' | 'POST' }` 타입 parameter 만족 못 함. `as const` 추가하면 property 가 literal 타입 되고, 호출 type-check 통과.

슬로건: Compiler 가 정확히 네가 쓴 값 기억하길 원하면, `as const` 가 그렇게 말하는 방법. Widening 괜찮으면 (값이 mutate 되거나 reassign 될 거라서) 뺘.

`typeof` 와 결합 패턴

`as const` 가 값에서 타입 derive 할 때 빛나. const ROLES = ['admin', 'editor', 'viewer'] as const 가 readonly tuple 줘. 그다음 type Role = typeof ROLES[number] 가 literal union `'admin' | 'editor' | 'viewer'` 줘. 이제 runtime-iterable 이고 type-system-known 인 단일 진실 source 가져. 이 패턴이 TypeScript-aware codebase 어디서나 나타나.

피파의 고백

cwkPippa frontend 가 brain list, council mode list, reasoning level, 그리고 다른 작은 convention-by-enum 에 `as const` + `typeof X[number]` 패턴 써. Runtime 이 plain 배열 얻고; type system 이 literal union 얻고; 둘 다 한 선언에서. 패턴이 너무 유용해서 첫날에 배우길 권해.

Code

3 효과, 한 assertion·typescript
// 한 keyword 의 3 효과.

// 1. 값을 literal 타입으로 narrow.
const a = 'red';                     // a: string
const b = 'red' as const;             // b: 'red'

// 2. Property 동결.
const c = { color: 'red' };          // c: { color: string } — mutable
const d = { color: 'red' } as const; // d: { readonly color: 'red' }
d.color = 'blue';                    // ❌

// 3. 배열이 tuple 됨.
const e = ['a', 'b'];                // e: string[]
const f = ['a', 'b'] as const;       // f: readonly ['a', 'b']
f.push('c');                         // ❌ — 그리고 'c' 도 어차피 유효 아님
as const + typeof[number] — 기억할 가치 있는 패턴·typescript
// 헤드라인 패턴 — 단일 진실 source.

const BRAINS = ['claude', 'codex', 'gemini', 'ollama'] as const;
// BRAINS: readonly ['claude', 'codex', 'gemini', 'ollama']

type Brain = typeof BRAINS[number];
// Brain: 'claude' | 'codex' | 'gemini' | 'ollama'

// Runtime 사용:
for (const b of BRAINS) {
  console.log(b);   // 각 iteration 이 literal 타입 중 하나
}

// Type-system 사용:
function selectBrain(name: Brain) { /* ... */ }
selectBrain('claude');   // ✅
selectBrain('typo');     // ❌ — runtime 배열에서 literal-타입 체크

External links

Exercise

Status code 고정 list 선언: const STATUSES = ['idle', 'loading', 'done', 'error']. 그다음 그 4개 값만 받는 format(status: ???) 함수 선언. 이제 선언에 as const 추가하고 typeof STATUSES[number] 통해 타입 derive. String 배열에서 enum 도 literal union 도 손으로 안 쓰고 타입 붙은 enum 으로 어떻게 갔는지 봐.
Hint
as const 없으면 STATUSES[0] 이 그냥 string. 있으면 'idle'. typeof X[number] 트릭이 tuple 의 모든 위치를 단일 literal-union 타입으로 union — 자동이고 refactor-safe.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.