타입스크립트 in 50 레슨

스테판 바움가트너가 스매싱 매거진에서 출판한 서적으로 타입스크립트 주요 주제들에 대해 잘 짚어주고 있다.

다루고 있는 주제는 아래와 같다.

  • 타입스크립트의 컨셉과 이해하기
  • 타입스크립트 툴 사용법과 효과적인 사용법
  • 뭔가 새로 배우지 않고 타입스크립트를 사용하는 법
  • 구조적 타입 시스템과 시멘틱 그리고 이게 왜 중요한지 이해하기
  • 유지 관리가 적은 타입을 만들고 재사용하는 법과 점진적으로 개선시키는 법
  • 프로젝트에 적합한 타입 시스템을 적용하는 법
  • 타입스크립트 커뮤니티와 언어가 개선되는 과정

기술적으로 다루는 내용은 아래와 같다.

  • 빨간 줄을 지워가는 과정
  • 타입을 다루는 방법
  • 함수와 함수 타입
  • 유니언 타입과 인터섹트 타입
  • 제너릭 (타입ed 클래스, 타입 파라미터)
  • 컨디셔널 타입
  • 프로그래밍과 타입에 대한 고민

홈페이지에서 예제 코드를 함께 제공하고 있다.

Lesson 1

빨간 줄을 활성화 하기

VSCode 기준으로 강의를 진행하고 있고 빨간 줄을 줄이자! 를 목표로 안전한 코딩을 하기 위해 타입스크립트가 어떤 도움을 주고 있는지 안내하고 있다.

코딩 과정에서 타입이 제공되면서 함수를 호출하고 인자를 처리하는데 단순한 오탈자 뿐 아니라 코드를 이해하고 적용하는 방법도 소개하고 있다.

'//@ts-check' 를 통해서 기존 자바스크립트에서 개선하는 노하우도 알려주고 있다.

//@ts-check
const storage = {
    max: undefined,
    items: []
}

Object.defineProperty(storage, 'max', { readonly: true, val: 5000 })

Lesson 2

타입 추론 기능으로 버그를 찾자

찾을 수 없는 프로퍼티를 사용해 발생하는 버그를 소개로 챕터를 시작한다. 이건 매뉴얼 보면서 코드를 작성하면 나오지 않을 문제긴 하지만 보통 실행 과정에서 예외가 발생하는 경우로 버그를 발견하고 해결하기 시작한다.

왜 빨간 줄이 그어지는지에 대한 내용으로 타입 추론에 대해 소개하고 있다. 약(Weak) 타입 언어 환경에서 식별자에 대한 타입을 추론하고 코딩 과정에서 해당 식별자의 타입을 제안하여 안전한 코드를 만들어가는 과정을 제안한다.

let currentStorage = undefined

function storageUsed() {
    currentStorage = 0
    return currentStorage
}

문법을 통해 식별자의 타입을 추론하는 기술도 가지고 있으니 VSCode 같은 자동 완성 기능을 포함한 환경을 제공하는 편집기를 사용하자.

for (const i = 0; i < storage.length(); i++) {
    currentStorage += storage.items[i].weigth
}

Lesson 3

구조적 타입 시스템을 제공하는 타입스크립트

타입은 무엇인가?

A type is a classification of data that defines the operations that can be done on that data, the meaning of the data, and the set of allowed values Typing is checked by the compiler and/or run time to ensure the integrity of the data, enforce access restrictions, and interpret the data as meant by the developer

  • Programming with Types, Vlad Riscutia

타입은; 해당 데이터에 대해 수행할 수 있는 작업을 구분하고, 데이터 스스로 의미를 규정하고, 컴파일러나 인터프리터가 오류없이 다룰 수 있는 값들에 대한 범위를 제한하며, 접근 제어를 강제하고, 개발자에게 데이터가 뭘 의미하는지 알려 준다.

내 경우, 로우레벨로 보면 타입은 이 자료가 메모리를 얼마나 차지하고 있느냐, 라고 소개하고 뭉개 버린다.

타입은 프로그래밍에 필수 요소다. 아닌 것 같지만 자바스크립트도 타입이 있다. number, string, boolean 이 대표적인 프리미티브 타입이다. object, array, function 등이 컴포지트 타입에 속한다.

자바스트립트는 타입이 있지만 동적 타입 언어에 속한다.

let val = 1234
val = 'Onetwothreefour'

정의된 식별자에 다른 타입의 값을 지정해도 잘 동작하고 심지어 다른 타입끼리 연산도 허용되기도 한다. 😬

let val = { a : 3 } + 5

강타입이 주는 이점은 여러가지가 있다. 타입스크립트는 자바스크립트를 강타입 언어로 한 번 더 포장해 준다.

그리고 Shape 이란 용어가 소개되는데 타입스크립트의 구조적structural 타입 시스템을 설명하기 위해 사용된 것으로 보면 된다.

const person = {
    firstName: 'Stefan',
    lastName: 'Baumgartner',
    age: 38
}

이 코드는

type Person = {
    firstName: string,
    lastName: string,
    age: number
}

이런 모양shape으로 표현된다.

이 모양에 대한 설명은 구조적 타입 시스템으로 계속 반복된다. (이에 상대되는 개념으로 nominal type system 이 있습니다.)

Lesson 4

바닐라 자바스크립트에 JSDoc 을 적용하여 타입 추론을 맛보기

점진적으로 자바스크립트 코드를 개선하는 방법으로 JSDoc 을 추가하여 사용하는 것을 권하고 있다.

타입 정보가 없는 자바스크립트 코드에 JSDoc 을 추가하여 타입 정보를 참조할 수 있게 해주고 이는 더 안전한 코드를 만들기 위한 기초로 사용된다.

/**
 * @typedef {Object} ShipStorage
 * @property {number} max
 * @property {StorageItem[]} items
 */
/** @type ShipStorage */
const storage = {
    max: undefined,
    items: []
}
//...
for (let i = 0; i < storage.length(); i++) {
    currentStorage += storage.items[i].weigth
}

커스텀 타입을 사용하여 타입 추론 기능을 사용할 수 있다면 더 안전한 코드를 작성할 수 있다.

Lesson 5

타입 선언 파일으로 타입을 재사용하기

타입스크립트는 자바스크립트의 수퍼셋으로 불리는데 이는 타입스크립트가 자바스크립트의 모든 것을 포함하고 있고 자바스크립트 보다 더 많은 부분을 가지고 있다는 뜻이다. 자바스크립트 코드는 타입스크립트 코드로 동작할 수 있지만 반대는 성립하지 못한다. 그래서 타입스크립트 코드를 브라우저나 노드JS 환경에서 직접 동작시킬 수 없다.

자바스크립트와 다른 첫번째 특징은 '.d.ts' 파일로 불리는 타입 선언 시스템이다. 선언된 타입들은 export 키워드로 선언하면 다른 파일에서 참조할 수 있다.

export type StorageItem = {
    weight: number
}

export type ShipStorage = {
    max: number,
    items: StorageItem[]
}

이 선언된 파일을 자바스크립트에서 사용하기 위해 '@ts-check' 아래에 이어

/** @typedef { import('./types.d').ShipStorage } ShipStorage */
/** @typedef { import('./types.d').StorageItem } StorageItem */

선언하여 타입 시스템을 활성화 시킬 수 있다.

Lesson 6

엠비언트 타입 정의 파일

타입 선언을 별도의 파일로 관리하고 재사용 할 수 있다면 더 나은 코딩 환경을 구성할 수 있다. 소스 코드를 수정하지 않고 전역으로 사용할 수 있는 타입을 선언하여 디버깅 환경을 활성화 시키는 기법도 있다.

jQuery 같은 라이브러리는 타입스크립트로 개발된 코드가 아니기에 별도의 타입 선언이 담긴 파일을 제공하지 않는다. 대신 앰비언트 타입 정의 파일을 추가하여 타입스크립트 개발 환경에 적용하자.

npm i @types/jquery

Lesson 7

타입스크립트의 도구들

NodeJS 패키지 매니저를 통해 타입스크립트 컴파일러를 설치하여 사용할 수 있다.

npm i -g typescript

'tsconfig.json' 파일은 타입스크립트 컴파일러의 컴파일 환경을 정의하고 있다.

  1. target: 컴파일러의 빌드 타겟.
  2. module: 빌드 파일의 모듈 시스템. commonjs 와 es2020 이 지원된다.
  3. esModuleInterop: 모듈 시스템과 결부되어 더 깊은 호환성을 제공한다.
  4. allowJs: .ts 파일이 아닌 .js 파일을 참조할 수 있게 허용한다.
  5. checkJs: 일반 자바스크립트 파일에도 타입 체크를 적용한다.
  6. typeRoots: 타입 정의 파일의 위치를 지정한다.

tsc 의 `–noEmit` 옵션과 `–watch` 옵션도 소개하고 있다.

Lesson 8

타입스크립트로 컴파일하기

타입스크립트는 브라우저에서 바로 실행되지 않기 때문에 컴파일을 하여 자바스크립트로 변환해야 한다. 자바스크립트 파일의 확장자를 `.ts` 로 바꿏는 것만으로도 타입스크립트 파일로 변경된다. `tsconfig.json` 파일을 생성하고 컴파일러 옵션을 정의하자.

{
    "compilerOptions": {
        "target": "ES2020",
        "module": "es2020",
        "typeRoots": [
            "@types",
            "node_modules/@types"
        ],
        "esModuleInterop": true,
    }
}

타입스크립트는 코드에 어노테이션을 추가하여 타입을 정의한다.

function addVAT(price: number, vat: numer = 0.2) {
    return price * (1 + vat)
}

const boom = addVAT('this is not a number!')