WEB/TypeScript

[TypeScript] 타입 추론, 타입 및 할당 단언, 타입 가드

devOhzl 2024. 8. 7. 11:18

타입 추론 (Inference)

추론 : 판단을 근거로 삼아 다른 판단을 이끌어 냄

 

모든 부분에 타입을 직접 지정할 필요는 없고, 꼭 필요한 부분에 타입을 지정해준다.

타입을 추론하기 위해서는 근거로 삼을 수 있는 판단이 필요하다.

초기화된 변수

let num = 12

 

기본값이 설정된 매개 변수, 반환 값이 있는 함수

function add(a: number, b = 2) {
	return a + b
}

 

숫자 데이터가 기본적으로 할당되므로, b에는 타입을 지정해주지 않아도 된다.

a,b 가 number 타입이므로, 반환 타입을 따로 지정하지 않아도 타입 추론이 가능하다.

 

👉 최대한 타입을 적게 적으면서 타입스크립트가 이해하지 못하는 곳에는 꼭 정확한 타입을 제공해주어야 한다.

 

타입 단언 (Assertions)

단언 : 주저하지 아니하고 딱 잘라 말함
  • 단원 키워드 - as
  • Non-null 단언 연산자  - !

예시 1

const el = document.querySelector('body') as HTMLBodyElement
el.textContent = 'Hello world';

const els = document.querySelector('body')
els!.textContent = 'Hello world';

단언 키워드 as를 사용하지 않으면 el 의 타입이 HTMLBodyElement | null 로 추론된다.

하지만 개발자는 body 태그가 null이 아닐 것이라는 확신이 있으므로 HTMLBodyElement 타입을 단언한다.

  • as 키워드를 선언해서 타입을 단언한다.
  • 단언 연산자 ! 를 사용해서 null이 아니라고 단언한다.

 

예시 2 (잘못된 타입단언)

function getNumber(x: number | null | undefined) {
	// return Number(x.toFixed(2)) --> error
	return Number((x as number).toFixed(2))
}
getNumber(3.1415)
getNumber(null)		// error

null, undefined 타입은 toFixed 메서드를 사용할 수 없으므로 타입 에러가 발생한다.

위 코드처럼 매개 변수 x에 타입단언을 하면 코드의 에러는 사라지지만, 실제로 동작하며  null 데이터가 들어온다면 에러가 발생한다.

 

예시 3

function getValue(x: string | number, isNumber: boolean) {
  if (isNumber) {
    return Number(x.toFixed(2))
  }
  return x.toUpperCase()
}

위의 코드에서 x가  string이나 number 타입인데, 두 개의 타입 모두에서 toUpperCase 메서드를 사용할 수 없다는 에러가 발생한다.

 

function getValue(x: string | number, isNumber: boolean) {
  if (isNumber) {
    return Number((x as number).toFixed(2))
  }
  return (x as string).toUpperCase()
}

getValue('hello world', false)    // 'HELLO WORLD'
getValue(3.1415, true)    // 3.14

개발자들이 알 수 있는 문법을 통해 작성된 코드가 있을 때 ts가 코드의 내용을 추론하지 못한다면

개발자가 코드의 내용을 확신할 때 타입을 단언해준다.

 

할당 단언 ( Assertion)

let num!: number
console.log(num)

num = 123

 

num 을 초기에 단언해주지 않는다면 콘솔을 찍을 때 num 변수에 값이 할당되지 않으므로 에러가 발생한다.

number 타입이 지정될 때 할당을 했다는 뜻으로 초기에 단언을 해주면서 코드 에러를 없앨 수 있다.

 

타입 가드 (Guards)

if 조건이나 기타 다양한 내용들을 통해 작성된 코드가 실제로 잘 동작할 수 있도록 코드 상에서 방어를 한다.

 

예제 1

function logText(el: Element) {
  console.log(el.textContent)
}

const h1El = document.querySelector('h1') as HTMLHeadingElement
logText(h1El)

ts 코드 에러를 막기 위해 HTMLHeadingElement로 타입 단언을 해줬지만,

실제 동작에서 화면에 h1 요소가 없다면 null이 출력되며 에러가 발생한다.

 

function logText(el: Element) {
  console.log(el.textContent)
}

const h1El = document.querySelector('h1') as HTMLHeadingElement

if(h1El) { 
  logText(h1El)
}

if (h1El instanceof HTMLHeadingElement){
  logText(h1El)
}

실제로 그 데이터가 존재할 때만 내용이 동작하게 만들어주는 타입 가드를 사용해서 해결할 수 있다.

 

if 조건이나 기타 다양한 내용들을 통해 작성된 코드가 실제로 잘 동작할 수 있도록 코드 상에서 방어를 한다.

 

예제 2

function add(val: string | number){
  let res = 'Result => '
  if (typeof val === 'number'){
    res += val.toFixed(2)
  } else {
    res += val.toUpperCase()
  }
  console.log(res)
}

add(3.141592)    	// 'Result => 3.14'
add('hello world')  // 'Result => HELLO WORLD'


👉 자바스크립트에서 중요하게 사용할 수 있는 스킬이며, 에러가 발생할 수 있는 상황 자체를 코드 상에서 방어한다 !