🌆
Sunset Archive
GitHubLinkedInBlog
  • litsynp
  • Archives
    • Projects
      • Let's Parking!
      • 맛집몬스터 (JMT Monster)
      • spring-x-demo Projects
    • Articles
      • My Thoughts on GitBook
      • Wake-on-LAN & RDP Setup
    • Learning
      • Languages
        • Rust
          • Useful Links
          • Syntax
          • Pointers
          • Dependencies
          • Logging
          • Phantom Types
          • Iterable
            • Optional Skip
        • Go
          • Useful Links
          • Structures
          • Zero Values
          • Error Handling
          • Dependency Injection
          • Project Layout
        • JavaScript/TypeScript
          • Basics
            • Types
              • [JS] Falsy Values
              • [TS] Types - unknown, any, never
            • Rest Parameters (...)
            • Spread Syntax (...)
            • Destructuing Assignment
            • CJS, AMD, UMD, ESM
          • Advanced
            • Conditional Destructuring Assignment
            • Type Guards
          • Miscellaneous
            • Dependency Injection in JS?
            • ESLint, Prettier, TypeScript
          • Node
            • Useful Links
            • General
              • V8 Engine
              • Version Management: NVM
              • Environment Variables
            • Database
              • Knex
        • C
          • Dynamic Multi-dimensional Arrays
        • Spring
          • General
            • @Import v.s. @ContextConfiguration
            • MessageSource
          • Kotlin+Spring
            • Kotlin Annotations (Use-Site Targets)
            • Handling Null in Request DTO
            • Handling Null in URL
          • Reactive Stack
            • Reactive API with Spring WebFlux
          • Spring Security
            • Google OAuth Setup
          • Spring Batch
            • Bulk Insert
        • Kotlin
          • val/var in Constructor
          • Initializer Blocks
          • Inheritance Modifiers (final, open, abstract)
          • Delegate Pattern
        • Java
          • Serialization
          • Random Number Generation
            • (1) Math.random() v.s. Random
            • (2) Random v.s. ThreadLocalRandom
        • Python
          • Version Management
        • Ruby
          • Installation
          • Getters & Setters
        • Elixir
        • Erlang
        • Flutter
        • AWS
          • AWS CLI
        • Terraform
          • Installation
          • Basics
      • Code
        • OOP
          • The 4 Basic Concepts of OOP
          • The SOLID Principles
          • GRASP
          • Spring POJO
          • Others
        • Functional Programming
          • Currying
          • Higher-Order Function
          • Closure
          • Monad
        • 공변성, 반공변성, 무공변성
        • Others
          • UUID
          • GraphQL
          • Multimedia
            • Streaming
          • Geography
            • 위도 (Latitude), 경도 (Longitude)
      • Tools
        • Nix
        • Mermaid
          • Flowchart
          • Sequence Diagram
          • Class Diagram
          • Entity Relationship Diagrams
        • VSCode
          • VSCode CLI
          • VSCode Extensions
        • JetBrains
          • IntelliJ - Open Projects in Tabs
          • Delete Leftover IDE Directories
        • vim
          • Commands
      • Books
        • 다재다능 코틀린 프로그래밍 (Programming Kotlin)
          • Pt 01. 코틀린으로 스크립팅 하기
            • Ch 01. 코틀린 시작하기
            • Ch 02. Java 개발자를 위한 코틀린 필수 사항
            • Ch 03. 함수를 사용하자
            • Ch 05. 콜렉션 사용하기
        • 오브젝트 (Object)
          • Ch.0 들어가며 - 프로그래밍 패러다임
          • Ch.1 객체, 설계
          • Ch.2 객체지향 프로그래밍
          • Ch.3 역할, 책임, 협력
          • Ch.4 설계 품질과 트레이드오프
          • Ch.5 책임 할당하기
          • Ch.6 메시지와 인터페이스
          • Ch.7 유연한 설계
          • Ch.8 의존성 관리하기
          • Ch.9 유연한 설계
          • Ch.10 상속과 코드 재사용
          • Ch.11 합성과 유연한 설계
          • Ch.12 다형성
          • Ch.13 서브클래싱과 서브타이핑
          • Ch.14 일관성 있는 협력
          • Ch.15 디자인 패턴과 프레임워크
          • End. 마치며 - 나아가기
          • 후기
        • 헤드 퍼스트 디자인 패턴 (Head First Design Patterns)
          • Ch.1 디자인 패턴 소개와 전략 패턴
          • Ch.2 옵저버 패턴
          • Ch.3 데코레이터 패턴
          • Ch.4 팩토리 패턴
          • Ch.5 싱글턴 패턴
          • Ch.6 커맨드 패턴
          • Ch.7 어댑터 패턴과 퍼사드 패턴
          • Ch.8 템플릿 메소드 패턴
          • Ch.9 반복자 패턴과 컴포지트 패턴
          • Ch.10 상태 패턴
          • Ch.11 프록시 패턴
          • Ch.12 복합 패턴
        • 이펙티브 타입스크립트 (Effective TypeScript)
          • Ch.1 타입스크립트 알아보기
            • Item 1 타입스크립트와 자바스크립트의 관계 이해하기
            • Item 2 타입스크립트 설정 이해하기
            • Item 3 코드 생성과 타입이 관계없음을 이해하기
            • Item 4 구조적 타이핑에 익숙해지기
            • Item 5 any 타입 지양하기
          • Ch.2 타입스크립트의 타입 시스템
            • Item 6 편집기를 사용하여 타입 시스템 탐색하기
            • Item 7 타입이 값들의 집합이라고 생각하기
            • Item 1-7 Study Summary
            • Item 8 타입 공간과 값 공간의 심벌 구분하기
            • Item 9 타입 단언보다는 타입 선언을 사용하기
            • Item 10 객체 래퍼 타입 피하기
            • Item 11 잉여 속성 체크의 한계 인지하기
            • Item 12 함수 표현식에 타입 적용하기
            • Item 13 타입과 인터페이스의 차이점 알기
            • Item 14 타입 연산과 제너릭 사용으로 반복 줄이기
            • Item 15 동적 데이터에 인덱스 시그니처 사용하기
            • Item 16 number 인덱스 시그니처보다는 Array, 튜플, ArrayLike를 사용하기
            • Item 17 변경 관련된 오류 방지를 위해 readonly 사용하기
            • Item 18 매핑된 타입을 사용하여 값을 동기화하기
          • Ch.3 타입 추론
            • Item 19 추론 가능한 타입을 사용해 장황한 코드 방지하기
            • Item 20 다른 타입에는 다른 변수 사용하기
            • Item 21 타입 넓히기
            • Item 22 타입 좁히기
            • Item 23 한꺼번에 객체 생성하기
            • Item 24 일관성 있는 별칭 사용하기
            • Item 25 비동기 코드에는 콜백 대신 async 함수 사용하기
            • Item 26 타입 추론에 문맥이 어떻게 사용되는지 이해하기
            • Item 27 함수형 기법과 라이브러리로 타입 흐름 유지하기
          • Ch.4 타입 설계
            • Item 28 유효한 상태만 표현하는 타입을 지향하기
            • Item 29 사용할 때는 너그럽게, 생성할 때는 엄격하게
            • Item 30 문서에 타입 정보를 쓰지 않기
            • Item 31 타입 주변에 null 값 배치하기
            • Item 32 유니온의 인터페이스보다는 인터페이스의 유니온을 사용하기
            • Item 33 string 타입보다 더 구체적인 타입 사용하기
            • Item 34 부정확한 타입보다는 미완성 타입을 사용하기
            • Item 35 데이터가 아닌, API와 명세를 보고 타입 만들기
            • Item 36 해당 분야의 용어로 타입 이름 짓기
            • Item 37 공식 명칭에는 상표를 붙이기
          • Ch.5 any 다루기
            • Item 38 any 타입은 가능한 한 좁은 범위에서만 사용하기
            • Item 39 any를 구체적으로 변형해서 사용하기
            • Item 40 함수 안으로 타입 단언문 감추기
            • Item 41 any의 진화를 이해하기
            • Item 42 모르는 타입의 값에는 any 대신 unknown을 사용하기
            • Item 43 몽키 패치보다는 안전한 타입을 사용하기
            • Item 44 타입 커버리지를 추적하여 타입 안전성 유지하기
          • Ch.6 타입 선언과 @types
            • Item 45 devDependencies에 typescript와 @types 추가하기
            • Item 46 타입 선언과 관련된 세 가지 버전 이해하기
            • Item 47 공개 API에 등장하는 모든 타입을 익스포트하기
            • Item 48 API 주석에 TSDoc 사용하기
            • Item 49 콜백에서 this에 대한 타입 제공하기
            • Item 50 오버로딩 타입보다는 조건부 타입을 사용하기
            • Item 51 의존성 분리를 위해 미러 타입 사용하기
            • Item 52 테스팅 타입의 함정에 주의하기
          • Ch.7 코드를 작성하고 실행하기
            • Item 53 타입스크립트 기능보다는 ECMAScript 기능을 사용하기
            • Item 54 객체를 순회하는 노하우
            • Item 55 DOM 계층 구조 이해하기
            • Item 56 정보를 감추는 목적으로 private 사용하지 않기
            • Item 57 소스맵을 사용하여 타입스크립트 디버깅하기
          • Ch.8 타입스크립트로 마이그레이션하기
            • Item 58 모던 자바스크립트로 작성하기
            • Item 59 타입스크립트 도입 전에 @ts-check와 JSDoc으로 시험해 보기
            • Item 60 allowJS로 타입스크립트와 자바스크립트 같이 사용하기
            • Item 61 의존성 관계에 따라 모듈 단위로 전환하기
            • Item 62 마이그레이션의 완성을 위해 noImplicitAny 설정하기
        • Dive Into Design Patterns
          • 디자인 패턴 소개
          • 소프트웨어 디자인 원칙들
          • 디자인 패턴 목록
          • 유용한 링크
        • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (System Design Interview)
          • Key Points
          • Real Life Systems
          • Engineering Blogs
        • Node.js 디자인 패턴 바이블 (Node.js Design Patterns 3rd Edition)
        • 리팩터링 2판 (Refactoring: 2nd Ed.)
          • 1장 리팩터링: 첫 번째 예시
          • 2장 리팩터링 원칙
          • 3장 코드에서 나는 악취
          • 4장 테스트 구축하기
Powered by GitBook
On this page
  • Widening (넓히기)
  • Widening을 제어하는 방법 1: const
  • Widening을 제어하는 방법 2: 타입 체커에 추가적인 문맥 제공하기
  • Widening을 제어하는 방법 3: const assertion (const 단언문 사용하기)
  • Summary

Was this helpful?

Edit on GitHub
  1. Archives
  2. Learning
  3. Books
  4. 이펙티브 타입스크립트 (Effective TypeScript)
  5. Ch.3 타입 추론

Item 21 타입 넓히기

Widening (넓히기)

책의 Item 7 타입이 값들의 집합이라고 생각하기에서 설명한 것처럼(적어두진 않았다.) 런타임에 모든 변수는 유일한 값을 가진다.

그러나 타입스크립트가 작성된 코드를 체크하는 정적 분석 시점에, 변수는 '가능한' 값들의 집합인 타입을 가진다.

  • 상수를 사용해서 변수를 초기화할 때 타입을 명시하지 않으면 타입 체커가 타입을 결정해야 한다.

  • 이 말은 지정된 단일 타입 값을 가지고 할당 가능한 값들의 집합을 유추해야 한다는 뜻이다.

TS에서는 이러한 과정을 'widening'이라고 부른다.

interface Vector3 { x: number; y: number; z: number }
function getComponent(vector: Vector3, axis: 'x' | 'y' | 'z') {
  return vector[axis]
}

let x = 'x' // 'widening'이 동작해 'string'으로 추론
let vec = { x: 10, y: 20, z: 30 }
getComponent(vec, x)
               // ~ 'string' 형식의 인수는 '"x" | "y" | "z"' 형식의 매개변수에 할당될 수 없습니다.

실행은 (런타임에 오류 없이) 잘 되지만 편집기에서 오류가 발생한다.

const mixed = ['x', 1]

mixed의 타입이 될 수 있는 후보는 엄청 많다. 나열을 좀 해보자면...

  • ('x' | 1)[]

  • ['x', 1]

  • [string, number]

  • readonly [string, number]

  • (string|number)[]

  • readonly (string|number)[]

  • [any, any]

  • any[]

타입스크립트는 작성자의 의도를 추측하는데, 이 경우에는 (string|number)[]로 추측한다. 그렇지만 사람의 마음을 읽을 수는 없기 때문에 추측한 답이 항상 옳지도 않다.

Widening을 제어하는 방법 1: const

let 대신 const를 사용하여 변수를 선언하면 더 좁은 타입이 된다.

const x = 'x' // 타입이 'x'
let vec = { x: 10, y: 20, z: 30 }
getComponent(vec, x) // OK

이제 x는 재할당될 수 없으므로 TS는 더 좁은 타입인 타입 'x'로 추론한다.

하지만 객체와 배열의 경우에는 여전히 const로 추론하기 어렵다. 따라서 객체를 한번에 만들어야 하는데, 이 내용은 Item 23에서 다룬다.

Widening을 제어하는 방법 2: 타입 체커에 추가적인 문맥 제공하기

함수의 매개변수로 값을 전달하는 등 문맥을 제공하면 된다. Item 26에서 타입 추론 과정에서 문맥의 역할에 대한 내용을 다룬다.

Widening을 제어하는 방법 3: const assertion (const 단언문 사용하기)

const 단언문(const assertion)과 변수 선언에 쓰이는 let, const와 혼동하지 말자.

const v1 = {
  x: 1,
  y: 2,
}  // 타입은 { x: number; y: number }

const v2 = {
  x: 1 as const,
  y: 2,
}  // 타입은 { x: 1; y: number }

const v3 = {
  x: 1,
  y: 2,
} as const  // 타입은 { readonly x: 1; readonly y: 2 }

값 뒤에 as const를 작성하면, TS는 최대한 좁은 타입으로 추론한다.

Summary

  • 타입스크립트가 넓히기(widening)을 통해 상수의 타입을 추론하는 법을 이해하자.

  • 동작에 영향을 줄 수 있는 방법인 const, 타입 구문, 문맥, as const에 익숙해지자.

PreviousItem 20 다른 타입에는 다른 변수 사용하기NextItem 22 타입 좁히기

Last updated 2 years ago

Was this helpful?