<aside> 💡 아이템 19~23 발표 준비 (A조)

</aside>

아이템 19 추론 가능한 타입을 사용해 장황한 코드 방지하기

타입 구문

let x: number = 12

// ✅ 다음처럼만 해도 충분하다. 타입이 number로 이미 추론되어 있다.
let x = 12;

복잡한 객체의 타입 추론

const person: {
  name: string
  born: {
    where: string
    when: string
  }
  died: {
    where: string
    when: string
  }
} = {
  name: 'Sojourner Truth',
  born: {
    where: 'Swartekill, NY',
    when: 'c.1797',
  },
  died: {
    where: 'Battle Creek, MI',
    when: 'Nov. 26, 1883',
  },
}

// ✅ 타입을 생략하고 다음처럼 작성해도 동일하다. 두 예제에서 person의 타입은 동일하다.
const person = {
  name: 'Sojourner Truth',
  born: {
    where: 'Swartekill, NY',
    when: 'c.1797',
  },
  died: {
    where: 'Battle Creek, MI',
    when: 'Nov. 26, 1883',
  },
}

배열의 타입 추론

// ✅ 배열의 경우도 객체와 마찬가지로 타입스크립트가 정확하게 추론한다.
function square(nums: number[]) {
  return nums.map(x => x * x)
}
const squares = square([1, 2, 3, 4]) // Type is number[]

문자열의 타입 추론

const axis1: string = 'x' // Type is string

// ✅ 타입스크립트가 추론한 "y"가 더 정확한 타입이다.
const axis2 = 'y' // Type is "y"

리팩터링

interface Product {
  id: number
  name: string
  price: number
}

function logProduct(product: Product) {
  const id: number = product.id
  const name: string = product.name
  const price: number = product.price
  console.log(id, name, price)
}

-----

// 🤔 id에 문자가 들어 있을 수 있음을 나중에 알게 된다면?
interface Product {
  id: string
  name: string
  price: number
}

function logProduct(product: Product) {
  const id: number = product.id
  // ~~ Type 'string' is not assignable to type 'number'
  const name: string = product.name
  const price: number = product.price
  console.log(id, name, price)
}

-----

// ✅ logProduct 함수 내의 명시적 타입 구문이 없었다면, 코드 수정 없이 타입 체커를 통과한다.
interface Product {
  id: string
  name: string
  price: number
}

// ✅ 비구조화 할당문을 사용해 구현하는 것이 낫다.
function logProduct(product: Product) {
  const { id, name, price } = product
  console.log(id, name, price)
}

매개변수에 타입 구문 생략하기

// ✅ base의 기본값이 10이기 때문에 타입이 number로 추론된다.
function parseNumber(str: string, base = 10) {
  // ...
}

namespace express {
  export interface Request {}
  export interface Response {
    send(text: string): void
  }
}
interface App {
  get(path: string, cb: (request: express.Request, response: express.Response) => void): void
}
const app: App = null!

// ❌ Don't do this: 타입 선언이 필요하지 않다.
app.get('/health', (request: express.Request, response: express.Response) => {
  response.send('OK')
})

// ✅ Do this:
app.get('/health', (request, response) => {
  response.send('OK')
})

타입이 추론될 수 있음에도 명시하고 싶은 상황