--- category: Unified tags: [auto-consolidated, technical-documentation] title: [[DeepReadonly|DeepReadonly]] last_updated: 2026-05-02 --- # [[DeepReadonly|DeepReadonly]] ## πŸ“Œ Brief Summary > DeepReadonlyλŠ” TypeScriptμ—μ„œ 객체의 λͺ¨λ“  μ€‘μ²©λœ ν”„λ‘œνΌν‹°μ— μž¬κ·€μ μœΌλ‘œ `readonly`λ₯Ό μ μš©ν•˜μ—¬ 데이터 ꡬ쑰 전체λ₯Ό μ™„μ „ν•œ λΆˆλ³€(immutable) μƒνƒœλ‘œ λ§Œλ“œλŠ” μ‚¬μš©μž μ •μ˜ μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ΄λ‹€ [1, 2]. κΈ°λ³Έ λ‚΄μž₯된 `Readonly` μœ ν‹Έλ¦¬ν‹°κ°€ 객체의 μ΅œμƒμœ„ μ†μ„±λ§Œ λ³΄ν˜Έν•˜λŠ” 얕은(shallow) λΆˆλ³€μ„±λ§Œμ„ μ œκ³΅ν•œλ‹€λŠ” ν•œκ³„λ₯Ό κ·Ήλ³΅ν•˜κΈ° μœ„ν•΄ κ³ μ•ˆλ˜μ—ˆλ‹€ [1-3]. μƒνƒœ κ΄€λ¦¬λ‚˜ μ„€μ • 객체와 같이, 객체 생성 이후 λ‚΄λΆ€μ˜ 단 ν•˜λ‚˜μ˜ 속성도 μˆ˜μ •λ˜μ§€ μ•Šμ•„μ•Ό 함을 μ—„κ²©ν•˜κ²Œ 보μž₯ν•΄μ•Ό ν•  λ•Œ 주둜 μ‚¬μš©λœλ‹€ [1, 4]. --- > μž¬κ·€μ  λΆˆλ³€μ„±(DeepReadonly)은 TypeScriptμ—μ„œ μ΅œμƒμœ„ μ†μ„±λΏλ§Œ μ•„λ‹ˆλΌ μ€‘μ²©λœ λ‚΄λΆ€ κ°μ²΄κΉŒμ§€ λͺ¨λ‘ λΆˆλ³€(immutable) μƒνƒœλ‘œ λ§Œλ“œλŠ” μ»€μŠ€ν…€ μœ ν‹Έλ¦¬ν‹° νƒ€μž… κΈ°λ²•μž…λ‹ˆλ‹€ [1-3]. λ‚΄μž₯ `Readonly` νƒ€μž…μ΄λ‚˜ `readonly` μˆ˜μ‹μ–΄κ°€ μ œκ³΅ν•˜λŠ” 얕은(shallow) μˆ˜μ€€μ˜ 보호 ν•œκ³„λ₯Ό κ·Ήλ³΅ν•˜κΈ° μœ„ν•΄ λ§€ν•‘ νƒ€μž…κ³Ό 쑰건뢀 νƒ€μž…μ„ κ²°ν•©ν•˜μ—¬ κ΅¬ν˜„ν•©λ‹ˆλ‹€ [1, 3-5]. 전체 데이터 ꡬ쑰의 변경을 λ°©μ§€ν•˜μ—¬ 트리 κ΅¬μ‘°λ‚˜ λ³΅μž‘ν•œ 쀑첩 데이터λ₯Ό λ‹€λ£¨λŠ” μƒνƒœ 관리 및 μ„€μ • 객체 λ“±μ—μ„œ 데이터 무결성을 보μž₯ν•˜λŠ” κ°•λ ₯ν•œ λ°©μ–΄μ±… 역할을 ν•©λ‹ˆλ‹€ [1, 3]. ## πŸ“– Core Content - **얕은 λΆˆλ³€μ„±μ˜ ν•œκ³„ 극볡:** TypeScriptκ°€ 기본으둜 μ œκ³΅ν•˜λŠ” `Readonly` νƒ€μž…μ€ 객체의 μ΅œμƒμœ„ μˆ˜μ€€(top-level) ν”„λ‘œνΌν‹°λ§Œ 읽기 μ „μš©μœΌλ‘œ μ œμ–΄ν•œλ‹€ [1, 2]. λ”°λΌμ„œ λ‚΄λΆ€μ˜ μ€‘μ²©λœ κ°μ²΄λŠ” μ—¬μ „νžˆ μˆ˜μ • κ°€λŠ₯ν•œ μƒνƒœλ‘œ λ‚¨κ²Œ λ˜μ–΄ 데이터 μ˜€μ—Όμ˜ μœ„ν—˜μ΄ μ‘΄μž¬ν•˜λŠ”λ°, κΉŠμ€ μˆ˜μ€€μ˜ λΆˆλ³€μ„±μ„ κ°•μ œν•˜κΈ° μœ„ν•΄μ„œλŠ” `DeepReadonly` νƒ€μž…μ΄ ν•„μš”ν•˜λ‹€ [1-3]. - **μž¬κ·€μ  κ΅¬ν˜„ 방식:** `DeepReadonly`λŠ” λ§€ν•‘ νƒ€μž…(Mapped Types)κ³Ό 쑰건뢀 νƒ€μž…(Conditional Types)을 κ²°ν•©ν•˜μ—¬ μž¬κ·€μ μœΌλ‘œ μ •μ˜λœλ‹€ [4]. 일반적으둜 `type DeepReadonly = { readonly [P in keyof T]: DeepReadonly };`와 같은 ν˜•νƒœλ‘œ μž‘μ„±λ˜μ–΄, μ€‘μ²©λœ 데이터 트리 ꡬ쑰의 λͺ¨λ“  ν•˜μœ„ 속성에 `readonly` μˆ˜μ‹μ–΄κ°€ 빠짐없이 μ μš©λ˜λ„λ‘ λ§Œλ“ λ‹€ [1, 2, 4]. - **적용 및 κ°€μš©μ„±:** 이 νƒ€μž…μ€ 데이터 무결성을 μ΅œμš°μ„ μœΌλ‘œ ν•˜λŠ” ν”„λ‘ νŠΈμ—”λ“œ μ•„ν‚€ν…μ²˜λ‚˜ λ³΅μž‘ν•œ μ‹œμŠ€ν…œμ—μ„œ 예기치 μ•Šμ€ 데이터 변경을 μ°¨λ‹¨ν•˜λŠ” κ°•λ ₯ν•œ 방패 역할을 μˆ˜ν–‰ν•œλ‹€ [4]. ν•˜μ§€λ§Œ `DeepReadonly`λŠ” ν˜„μž¬ TypeScript μ–Έμ–΄ μžμ²΄μ— λ‚΄μž₯λ˜μ–΄ μžˆμ§€ μ•Šλ‹€ [5]. λ”°λΌμ„œ κ°œλ°œμžκ°€ ν”„λ‘œμ νŠΈ λ‚΄μ—μ„œ 직접 μž¬κ·€μ  μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ„ μ„ μ–Έν•˜κ±°λ‚˜, `ts-essentials`와 같이 이λ₯Ό μ œκ³΅ν•˜λŠ” μ„œλ“œνŒŒν‹° 라이브러리λ₯Ό 가져와 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€ [5]. --- - **얕은 λΆˆλ³€μ„±μ˜ ν•œκ³„:** TypeScript의 λ‚΄μž₯ `Readonly` μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ΄λ‚˜ 기본적인 `readonly` μˆ˜μ‹μ–΄λŠ” 객체의 μ΅œμƒμœ„(top-level) μ†μ„±λ§Œ 읽기 μ „μš©μœΌλ‘œ λ§Œλ“ λ‹€ [1, 2, 5]. 이둜 인해 μ€‘μ²©λœ 객체(nested objects)λ‚˜ λ°°μ—΄μ˜ κΉŠμ€ λ‚΄λΆ€ 속성듀은 μ—¬μ „νžˆ λ³€κ²½ κ°€λŠ₯ν•œ(mutable) μƒνƒœλ‘œ 남아 예기치 μ•Šμ€ 데이터 μ˜€μ—Όμ— μ·¨μ•½ν•΄μ§„λ‹€ [1, 2, 5]. - **DeepReadonly의 λ™μž‘ 원리:** μ΄λŸ¬ν•œ ν•œκ³„λ₯Ό κ·Ήλ³΅ν•˜κΈ° μœ„ν•΄ λͺ¨λ“  λ‚΄λΆ€ 계측을 λ³΄ν˜Έν•  수 μžˆλŠ” `DeepReadonly` μž¬κ·€μ  νƒ€μž…(Recursive Type)을 μ •μ˜ν•œλ‹€ [1, 2]. 이 νƒ€μž…μ€ λ§€ν•‘ νƒ€μž…(Mapped Types)κ³Ό 쑰건뢀 νƒ€μž…(Conditional Types)을 κ²°ν•©ν•˜μ—¬ κ΅¬μ„±ν•˜λ©°, 객체의 ν”„λ‘œνΌν‹°λ₯Ό μˆœνšŒν•˜λ©° μ€‘μ²©λœ λͺ¨λ“  속성에 μž¬κ·€μ μœΌλ‘œ `readonly`λ₯Ό κ°•μ œν•˜μ—¬ 전체 ꡬ쑰λ₯Ό λ™κ²°μ‹œν‚¨λ‹€ [1, 3]. - **κ΅¬ν˜„ 및 라이브러리 μ˜μ‘΄μ„±:** `DeepReadonly`λŠ” ν˜„μž¬ TypeScript 언어에 기본적으둜 λ‚΄μž₯된 μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ΄ μ•„λ‹ˆλ‹€ [6]. λ”°λΌμ„œ μ‹œμŠ€ν…œ 무결성을 μœ„ν•΄ κ°œλ°œμžκ°€ 직접 μž¬κ·€μ  헬퍼 νƒ€μž…μ„ μ •μ˜ν•˜κ±°λ‚˜, `ts-essentials`와 같이 이λ₯Ό μ œκ³΅ν•˜λŠ” μ™ΈλΆ€ λΌμ΄λΈŒλŸ¬λ¦¬μ— μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€ [6]. λ°˜λŒ€λ‘œ λΆˆλ³€μ„±μ„ ν•΄μ œν•΄μ•Ό ν•˜λŠ” κ²½μš°μ—λŠ” `Mutable` 헬퍼 νƒ€μž…μ„ λ§Œλ“€μ–΄ λͺ¨λ“  μ†μ„±μ˜ `readonly`λ₯Ό μ œκ±°ν•  μˆ˜λ„ μžˆλ‹€ [2, 7]. - **핡심 ν™œμš© 사둀:** 트리 κ΅¬μ‘°λ‚˜ λ³΅μž‘ν•œ 쀑첩 데이터λ₯Ό λ‹€λ£° λ•Œ 단 ν•˜λ‚˜μ˜ 속성도 λ³€κ²½λ˜μ§€ μ•Šλ„λ‘ 보μž₯ν•œλ‹€ [1, 3]. 생성 ν›„ ꡬ쑰가 μˆ˜μ •λ˜μ–΄μ„œλŠ” μ•ˆ λ˜λŠ” μ„€μ • 객체(Configuration objects), μƒνƒœ 관리 μ•„ν‚€ν…μ²˜, 그리고 데이터 무결성이 치λͺ…μ μœΌλ‘œ μ€‘μš”ν•œ 금육 μ‹œμŠ€ν…œ λ“±μ—μ„œ ν•„μˆ˜μ μΈ 보호 μš”μ†Œλ‘œ 자리 작고 μžˆλ‹€ [1, 3, 8]. ## βš–οΈ Trade-offs & Caveats - **κ³Όκ±° λ°μ΄ν„°μ™€μ˜ 좩돌:** μžλ™ν™” 엔진에 μ˜ν•΄ λ§€ν•‘λœ μ§€μ‹μœΌλ‘œ, μΆ”ν›„ μ •λ°€ 검증 ν•„μš”. - **μ •μ±… λ³€ν™”:** Programming & Language λΆ„μ•Όμ˜ μžλ™ μžμ‚°ν™” μˆ˜ν–‰. --- - **κ³Όκ±° λ°μ΄ν„°μ™€μ˜ 좩돌:** μžλ™ν™” 엔진에 μ˜ν•΄ λ§€ν•‘λœ μ§€μ‹μœΌλ‘œ, μΆ”ν›„ μ •λ°€ 검증 ν•„μš”. - **μ •μ±… λ³€ν™”:** Programming & Language λΆ„μ•Όμ˜ μžλ™ μžμ‚°ν™” μˆ˜ν–‰. ## πŸ”— Knowledge Connections - **Related Topics:** [[readonly|readonly]], Readonly, Mapped Types, Conditional Types - **Projects/Contexts:** [[ᄉᅑᆼᄐᅒ α„€α…ͺᆫ라(State Management)|μƒνƒœ 관리(State Management]], μ„€μ • 객체(Configuration Objects), ts-essentials - **Contradictions/Notes:** κΉŠμ€ μˆ˜μ€€μ˜ λΆˆλ³€μ„±μ„ 보μž₯ν•˜λŠ” κΈ°λŠ₯이 μ‹€λ¬΄μ μœΌλ‘œ 널리 μš”κ΅¬λ˜μ—ˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  `DeepReadonly`λŠ” TypeScript에 κ³΅μ‹μ μœΌλ‘œ κΈ°λ³Έ λ‚΄μž₯λ˜μ–΄ μžˆμ§€ μ•Šλ‹€λŠ” 점이 νŠΉμ§•μ μ΄λ‹€ [5]. 이둜 인해 좔가적인 κ΅¬ν˜„μ΄λ‚˜ μ™ΈλΆ€ 라이브러리 μ˜μ‘΄μ„±μ΄ μš”κ΅¬λœλ‹€ [5]. --- *Last updated: 2026-04-18* --- --- - **Related Topics:** [[Readonly 유탈라타 ᄐᅑ압|Readonly]], λ§€ν•‘ νƒ€μž… (Mapped Types), 쑰건뢀 νƒ€μž… (Conditional Types), μœ ν‹Έλ¦¬ν‹° νƒ€μž… (Utility Types) - **Projects/Contexts:** ts-essentials, ν”„λ‘ νŠΈμ—”λ“œ μƒνƒœ 관리 ([[State|State]] [[Management|Management]]), μ„€μ • 객체 (Configuration objects) - **Contradictions/Notes:** `Readonly`λŠ” κΈ°λ³Έ μ œκ³΅λ˜λ‚˜ `DeepReadonly`λŠ” TypeScript에 λ‚΄μž₯λ˜μ–΄ μžˆμ§€ μ•Šλ‹€λŠ” 점이 νŠΉμ§•μž…λ‹ˆλ‹€ [6]. λ˜ν•œ λŸ°νƒ€μž„μ— μ„±λŠ₯ μ˜€λ²„ν—€λ“œλ₯Ό μΌμœΌν‚€λŠ” `Object.freeze()`의 얕은 동결과 달리, 이 방식은 컴파일 νƒ€μž„μ— νƒ€μž… λ ˆλ²¨μ—μ„œλ§Œ λΆˆλ³€μ„±μ„ κ²€μ‚¬ν•˜κ³  κ°•μ œν•˜λ―€λ‘œ 훨씬 νš¨μœ¨μ μž…λ‹ˆλ‹€ [5]. --- *Last updated: 2026-04-18* ---