ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [패캠] 타입스크립트 문법 - 타입 및 할당 단언 (Assertion) (5/20)
    Front-end 개발 2024. 2. 1. 14:35

    Fastcampus 프론트엔드 개발 강의

     

    💡 본 타입스크립트 문법 시리즈는,
         패캠의 '프론트엔드 웹 개발의 모든 것 초격차 패키지 Online'에 있는 TS 강의 노트이다.

     

    현재 수강 중인 패스트캠퍼스(fastcampus, 이하 패캠) 프론트엔드 패키지 강의가 있다.

    강사님은 김영웅(Heropy) 님이다.

    이 글을 쓰면서 강사님의 블로그에 '한눈에 보는 타입스크립트' 자료가 있다는 것을 알게 됬다... (바보😅)

     

    강의를 듣는데, 강의자료가 없어서 일일이 강사님이 말씀을 따라 적으면서 강의 교안(?), 강의 노트를 작성했다.

    혹시나 나처럼 패캠에서 타입스립트(TypeScript)를 수강하는 사람들에게 도움이 되면 좋겠다. 🔥

     

    05. 타입 및 할당 단언 (Assertions)


    타입스크립트 코드를 작성하면서 굉장히 중요한 개념이다. 어렵지 않은 내용이지만 잘못 사용하게 되면, any 타입과 같이 타입스크립트를 사용하는 이유가 없어질 수 있다. 그렇기 때문에 잘 이해하고 사용해야 한다.

    단언(Assertion) : 주저하지 아니하고 딱 잘라 말함

     

    즉, 우리 개발자가 타입스크립트에게 딱 잘라서 얘기 하는 것이다.

     

    두가지 단언 방식

    1. 단언 키워드: as
    2. Non-null 단언 연산자: !

    단언 키워드 (as)

    document 의 querySelector라는 메서드는 선택자를 제공해서 그 선택자로 요소를 찾지 못하면 null 데이터를 반환한다. 그렇기 때문에 아래의 예시 코드에서 타입스크립트는 body 태그 선택자를 이용해 요소를 못 찾을 수도 있다고 에러 메시지를 띄운다.

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

    타입 단언을 해주지 않았을 때, 발생하는 Error

    기본적으로 html 구조를 만들면 당연하게 body 태그를 추가 한다. 그래서 개발자들은 현재 프로젝트 document에 body 태그가 존재한다는 것을 명확하게 알고 있다.

    하지만 타입스크립트는 어디까지나 스크립트 코드에서만 타입을 추론을 하기 때문에 body 태그가 실제로 html에 존재하는지는 타입스크립트 입장에서는 알 수 있는 방법이 없다. 이 상황에서는 당연히 개발자가 타입스크립트보다 현재 코드에 대한 확신을 가지고 있다. 이러한 경우에 타입스크립트에게 주저하지 않고 딱 잘라서 (단언하여) body 태그가 있다는 것을 표시할 수 있다.

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

    타입스크립트 입장에서는 단언을 해주면 개발자가 확신이 있다고 판단하여 더 이상 에러가 발생하지 않는다.

    주의할 점은 잘못된 타입 단언을 하게 되면 코드 상에서는 에러가 발생하지 않기 때문에 잘못된 코드인지는 일단 코드를 실행해 보기 전까지는 알 수가 없다. 그렇기 때문에 타입 단언을 잘 사용해야 한다.

    코드 상에서는 문제가 없지만, 타입스크립트에서는 에러가 발생하는 경우도 있다.

    function getValue(x: string | number, isNumber: boolean) {
        if (isNumber) {
            return Number(x.toFixed(2))
        }
        return x.toUpperCase()
    }
    getValue('hello world', false) // 'HELLO WORLD'
    getValue(3.1415926535, true) // 3.14
    

    코드 상에 문제가 없지만 TS에서 에러가 발생하는 경우

     

    위 코드를 단언을 사용하여 에러를 수정할 수 있다.

    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
    

    메서드(속성)를 사용하는 곳에 타입 단언 키워드(as)를 사용할 때는 문법적으로 정확하게 어디에서 실행되는지 소괄호를 사용하여 명시해준다.

    위와 같은 방식으로 개발자들이 알 수 있는 문법을 통해서 작성된 코드를 타입스크립트가 이런 코드의 내용을 추론해서 이해하지 못한다면 우리가 확신하고 있는 타입을 타입스크립트에게 딱 잘라서 해당 부분에 문제가 없다고 단언해 줄 수 있다.

    Not-null 단언 연산자 (!)

    단언을 사용하는 다른 문법으로 첫 번째 예시의 에러를 해결할 수 있다.

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

    documet의 querySelector 메서드를 통해서 요소를 찾는데, 요소를 찾지 못하면 null 데이터가 반환될 수 있다. element가 null이라면 textContent 속성을 사용할 수가 없다. 이때 Non-null 단언 연산자(!)를 사용하여 느낌표 안쪽에 있는 el 변수는 절대 null 또는 undefined가 아니라고 단언해줄 수 있다. 타입스크립트는 개발자를 통해서 단언을 받았기 때문에 더 이상 에러를 발생하지 않는다.

    Type Guard

    첫 번째 예제를 단언 키워드와 Not-null 단언 연산자를 통해서 해결할 수 있었지만, body 대신 다른 태그가 들어간다면 다시 에러가 발생할 수 있다. 이 경우에는 el 변수에 데이터가 있을 경우, 즉 querySelector가 요소를 잘 찾게 되면 null 데이터가 아닐테니 물리적으로 if 조건 안으로 들어갈 수 있는 상황이 된다. 이렇게 if 조건을 통해서 물리적으로 el 변수가 있을 때만 textContent 속성을 사용하도록 만들어주면 타입스크립트랑 상관없이 실제 JavaScript 코드를 통해서 문제를 해결할 수가 있다.

    if 조건을 사용하여 el 변수의 내용이 확정적일 때만 코드가 동작하도록 만들어주는 방식을 Type Guard 라고 한다.

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

    변수가 union 타입으로 다양한 타입을 가질 수 있는 경우에 Type Guard를 적용해 볼 수 있겠다.

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

    타입 단언은 다시 한번 말하지만 개념 자체는 어렵지 않다. 하지만 잘못 사용하게 될 수 있기 때문에 타입 단언 문법을 남발하는 것은 좋지 않다. 그렇기 때문에 내용을 잘 이해하고 사용해야 한다. 타입 단언 만으로 해결할 수 없는 부분은 Type Guard를 사용할 수도 있다.

    할당 단언 (!:)

    아래 예제와 같이 타입을 지정하지 않았다면 아무런 에러가 발생하지 않지만, 타입을 지정하면서 num2 변수 부분에 할당되기 전에 사용되었다는 에러가 발생한다.

    let num2: number
    console.log(num2) // error
    

    변수 할당 전에 사용하여 발생하는 에러

    타입스크립트 입장에서는 엄격하게 값이 number 타입 변수에 숫자형의 데이터가 할당되지 않은 상태로 변수가 사용되고 있다고 에러를 표시하는 것이다.

    이때 개발자는 num2 변수에 할당이 된 것처럼 단언을 해줄 수 있다. num2 변수에 아무런 값도 할당하지 않았지만 타입스크립트에게 해당 부분의 내용은 할당을 했다고 단언하는 것이다.

    let num2!: number
    console.log(num2) // error가 발생하지 않는다
    
    num2 = 123
    

    할당 단언의 사용 방법은, 타입을 지정하는 콜론 기호(:) 앞에서 느낌표(!) 기호를 사용하여 할당을 단언한다.

    어떻게 보면 할당 단언은 타입스크립트에게 거짓말을 하는 것인데, 결국에 내가 원하는 코드를 만들기 위해서 어쩔 수 없이 하는 선의의 거짓말 정도로 이하면 되겠다. 그래서 타입스크립트에게 이 변수는 이미 할당된 구조이니 에러를 발생할 필요가 없다고 딱 잘라서 단언을 하는 것이다.

     

     

     

    Reference


    김영웅 강사님 블로그 中 TS 파트

    https://heropy.blog/2020/01/27/typescript/

     

    한눈에 보는 타입스크립트(updated)

    타입스크립트는 Microsoft에서 개발하고 유지/관리하는 Apache 라이센스가 부여된 오픈 소스로, 자바스크립트에 강한 타입 시스템을 적용해 대부분의 에러를 컴파일 환경에서 코드를 입력하는 동안

    heropy.blog

     

    김영웅 강사님 유튜브 채널

    https://www.youtube.com/channel/UCcjhMpoaNvyy0StN9KgtF6w

     

    HEROPY

    안녕하세요! 박영웅 강사입니다. 행복한 하루 보내세요~🍀 깃헙) https://github.com/ParkYoungWoong 메일) thesecon@gmail.com 현) 질링스 B2G 개발팀 프론트엔드 리더 기타 활동) - 시그니처, 초격차, 올인원, UX/

    www.youtube.com

     

Designed by Tistory.