# 글의 목적

인하우스 서비스 구축하며 사용했던 TypeScript의 문법들을 정리한다. 어떤 것을 알고 있는 지 식별하기 위함과 생산성을 위한 최소한의 문법들을 정리하기 위함이다.

# 기본 타입

Basic Types

const canDelete: boolean = false
const num: number = 0
const str: string = 'string'
const strArr: string[] = ['string', 'string']
const tuple: [string, number] = ['string', 0]
const nullType: null = null
const undefinedType: undefined = undefined
const obj: object = {key: 'value'}
enum Phase {
  Sandbox = 'sandbox',
  Beta = 'beta',
  Production = 'production'
}
let anyType: any = 0 // anything
anyType = 'string' // Ok
anyType = ['string'] // Ok

Type assertions는 특정 DOM 타입을 사용할 때 유용하다.

const str: any = 'this is a string'
const len: number = (str as string).length

# 사용자 타입 정의

# function

Function Types

const add: (x: number, y: number) => number = (x, y) => x + y

# Interface

Interfaces

interface DateOption {
  readonly year: number
  month: number
}

interface CalendarOption extends DateOption {
  day: number
}

# class

Class Expressions

class ToggleHelper {
  private state: boolean
  private constructor(state: boolean) {
    this.state = state
  }
  static create(state = false): ToggleHelper {
    return new ToggleHelper(state)
  }
  on(): void {
    this.state = true
  }
  off(): void {
    this.state = false
  }
  toggle(): void {
    this.state = !this.state
  }
  get isOn(): boolean {
    return this.state
  }
}

// new ToggleHelper() Error!
ToggleHelper.create() // Ok

# namespace

namespace

namespace MyBackendApi {
  interface Request {}
  interface Response {}
}

# Generic

Generic

type NoticeKey<T> = {
  notice_key: T
}

type SingleNoticeKey = NoticeKey<number>
type MultiNoticeKey = NoticeKey<number[]>

# type

Type Aliases

type Callback = () => void
type SingleNoticeKey = NoticeKey<number>
type MultiNoticeKey = NoticeKey<number[]>

# declare

Reusable Types Interfaces

declare namespace GetNotice {
  interface Request {}
  interface Response {}
}
declare namespace GetNoticeList {
  interface Request {}
  interface Response {}
}

# 타입 조합하기

# Intersection Types

Intersection Types

interface YearField {
  year: number
}
interface MonthField {
  month: number
}
interface DayField {
  day: number
}

type DateOption = YearField & MonthField & DayField

const option: DateOption = {
  year: 2020,
  month: 2,
  day: 10,
}

# Union Types

Union Types

let option: DateOption | null = null
option = {
  year: 2020,
  month: 2,
  day: 10,
}

# keyof

keyof and lookup types

type DateOptionKey = keyof DateOption

const keys: DateOptionKey[] = [
  'year', 'month', 'day'
]
const keys2: DateOptionKey[] = [
  'seconds' // Wrong
]

# key 선언

interface ReadonlyDictionary {
  readonly [key: string]: any
}

const API_CONFIG: ReadonlyDictionary = {
  PROTOCOL: 'https',
  HOST: 'my.api.com',
  PORT: '443',
}

API_CONFIG.PROTOCOL = 'http' // Wrong!
enum Phase {
  Sandbox = 'sandbox',
  Beta = 'beta',
  Production = 'production'
}

type PhaseHost = {
  readonly [key in Phase]: string
}

const PHASE_CONFIG: PhaseHost = {
  [Phase.Sandbox]: 'my-sandbox.api.com',
  [Phase.Beta]: 'my-beta.api.com',
  [Phase.Production]: 'my.api.com',
  'cbt': 'my-cbt.api.com' // Wrong
}

# Mapped Types

Partial

interface DateOption {
  year: number
  month: number
  day: number
}

type DateOptionPartial = Partial<DateOption>

const yearKey: DateOptionPartial = {
  year: 2020
}
const monthKey: DateOptionPartial = {
  month: 2
}
const calendarOption: DateOptionPartial = {
  year: 2020,
  month: 2
}
const selectedDay: DateOptionPartial = {
  year: 2020,
  month: 2,
  day: 10
}

Pick

interface DateOption {
  year: number
  month: number
  day: number
}

const calendarTitle: Pick<DateOption, 'year' | 'month'> = {
  year: 2020,
  month: 2,
  day: 10 // Wrong
}

# Postfix

# Definite Assignment Assertions

Definite Assignment Assertions

// Wrong
let x: {num: number}
init()
const y = x.num + x.num
function init() {
  x = {num: 1}
}

// Ok
let x!: {num: number}
init()
const y = x.num + x.num // Wrong
function init() {
  x = {num: 1}
}

# Optional parameters and properties

Optional parameters and properties

interface DateOption {year: number, month: number}

function toTitle(dateOption?: DateOption): string {
  return  dateOption ? `${dateOption.year}.${dateOption.month}` : ''
}

const option: DateOption = {year: 2020, month: 2}
toTitle(option) // '2020.2'
toTitle() // ''

# 논외

TypeScript 버전에 따른 추가된 문법 정리.

# 끄읕