늘 겸손하게

TypeScript - 타입 및 할당 단언 본문

Programming/TypeScript

TypeScript - 타입 및 할당 단언

besforyou999 2023. 11. 1. 21:07

 

 

단언?

 

단언은 '주저하지 않고 딱 잘라 말한다'는 의미이다.

 

데이터 타입을 개발자가 딱 잘라서 정하는 것을 '단언'이라 한다.

 

변수에 할당 가능한 데이터 타입이 여러가지일 경우 타입스크립트는 어떤 타입의 데이터가 할당될지 알 수 없는 경우가 있다.

이때 개발자는 단언을 통해 할당되는 데이터 타입을 결정한다.

 

const el = document.querySelector('body')
el.textContent = 'Hello world?!'

 

식별자 el에는 HTMLBodyElement 혹은 null 타입의 데이터가 할당될 수 있다. ('body' 요소가 없을 수 있으니)

타입스크립트는 el에 할당될 데이터 타입이 어떤 타입인지 알 길이 없다.

이러한 경우 개발자가 el 에 할당될 데이터의 타입은 '단언'하여야 한다.

 

 

단언 키워드 - as

 

예시 1

const el = document.querySelector('body')
el.textContent = 'Hello world?!'

 

식별자 el에는 HTMLBodyElement 혹은 null 타입의 데이터가 할당될 수 있다. ('body' 요소가 없을 수 있으니)

 

타입스크립트는 el에 할당될 데이터 타입이 어떤 타입인지 알 길이 없다.

 

이러한 경우 개발자가 el 에 할당될 데이터의 타입은 '단언'하여야 한다.

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

 

 

예시 2

function getNumber(x: number | null | undefined) {
  return Number(x.toFixed(2))
}

 

x에 null, undefined 타입 데이터 또한 할당되면 to.Fixed() 호출이 불가능하므로 타입스크립트는 오류를 출력한다.

 

여기서 as를 통해 '단언'을 하여 오류를 해결한다.

 

function getNumber(x: number | null | undefined) {
  return Number((x as number).toFixed(2))
}

 

 

예시 3

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

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

 

타입스크립트는 x.toFixed(2) 와 x.toUpperCase() 부분에서 오류를 출력한다.

string에는 toFixed가 없고 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.1415926535, true); // 3.14

 

 

Non-null 단언 연산자 '!'

 

할당되는 데이터 타입은 절대 null이나 undefined가 아니다 라는 의미.

// Non-null 단언 연산자 : !
// 할당되는 데이터 타입은 절대 null이 아니다 라는 의미
const el = document.querySelector('body')
el!.textContent = 'Hello world?!'

 

function getNumber(x: number | null | undefined) {
  return Number(x!.toFixed(2))
}

 

하지만 첫 번째 예시에서 'body' 태그가 아닌 '.title' 클래스의 요소를 찾는데 html에 .title 클래스의 요소가 없다면? 

타입스크립트 오류는 보이지 않아도 코드가 제대로 동작하지 않을 것.

 

위와 같은 문제 해결을 위해 if문을 사용하는 방법이 있다.

const el = document.querySelector('body')
if (el) {
  el.textContent = 'Hello world?!'
}

 

위와 같은 코드는 찾아낸 요소가 없으면 el에 null이 할당되고 3줄은 절대 실행되지 않을 것이다.

위와 같은 방식을 타입 가드(Guards)라 부른다.

 

 

할당 단언

 

let num: number
console.log(num)

 

 

TypeScript는 위 처럼 코드를 작성하면 아래와 같은 에러를 출력한다.

 

 

 

말 그대로 변수를 할당되기 전에 사용해서 엄격한 규칙을 지닌 타입스크립트는 오류를 출력합니다.

 

만약 개발자가 예시와 같은 코드를 의도적으로 작성하려면 할당 단언을 사용할 수 있습니다.

 

let num!: number
console.log(num)