[한입챌린지]타입스크립트 DAY4

Lina Hongbi Ko·2025년 3월 2일
0
post-thumbnail

DAY4

2025년 2월 28일

✨ Any 타입

  • 특정 변수의 타입을 우리가 확실히 모를 때 사용

  • 타입스크립트는 초기화 하는 값을 기준으로 변수의 타입을 자동 추론함

  • 자바스크립트 변수를 쓰듯이, 아무값이나 담을 수 있게 하려면 any타입을 설정하면 됨

  • any 타입은 모든 타입의 값을 할당 받을 수 있고, 반대로 모든 타입의 변수에 다 any 타입의 값을 집어 넣을 수도 있음

  • 어떤 타입의 메서드를 사용해도 됨

  • 타입스크립트의 타입 검사를 모두 통과하는 치트키 같은 것임

    • 그런데, 자바스크립트 코드로 변환하면 오류가 발생함 -> 런타임에 오류가 발생함
  • 따라서, any 타입은 가능한 한, 최대한 사용하지 않는 것이 좋음!!!

    // any
    
    let anyVar: any = 10;
    anyVar.toUpperCase();
    
    let num: number = 10;
    num = anyVar;

✨ Unknown 타입

  • any와 비슷한 타입임 (아무 타입의 값을 다 집어 넣을 수 있음)

  • 만약 변수에 어떤 타입이 들어올지 모를때, any와 unknown 둘 중하나를 쓸 수 있음

  • 그러나, 차이가 있음!!

  • unknown 타입은 모든 값을 저장할 수는 있지만, 반대는 안됨(any는 가능)

  • any와는 다르게 메서드를 사용 수 없고, 연산도 안됨

    • unknown 값을 활용하고 싶다면, 자바스크립트의 typeof 연산자를 이용해서 타입을 확실히 설정해줬을 때에만 unknown타입을 해당 타입으로 정제해서 사용할 수 있음
  • 따라서, 우리가 변수에 저장할 값의 타입이 확실하지 않을때는 any타입보다는 조금 더 안전한 unknwon 타입을 활용하는 것이 좋음!

    • 아무 연산이나 아무 메서드나 아무 변수에 값을 넣을 수 없어서 런타임 에러를 일으키는 any 타입보다는 나음!
    // unknown
    let unknownVar: unknown;
    unknownVar = '';
    unknownVar = 1;
    unknownVar = () => {};
    
    let num: number = 10;
    num = unknownVar // 오류
    num.toUpperCase() // 오류
    
    if(typeof unknownVar === 'number') {
      num = unknownVar;
    }

✨ Void 타입

  • 타입스크립트에서는 함수 반환값의 타입을 지정할 수도 있음

  • 아무런 값도 반환하지 않을때 void 타입을 사용함

  • 변수에도 void 타입을 정의할 수 있음

    • 그러나, void 타입으로 정의한 변수에는 어떠한 값도 담을 수 없음 (문자열, 객체, 등 담을 수 없고 오직 undefined만 담을 수 있음)
    • tsconfig.json 옵션에서 'strictNullChecks'를 false로 설정하면 null을 할당할 순 있음
  • 굳이 반환값이 없는 함수의 타입의 반환값을 정의할 때 undefined 이나 unknwon을 쓰지 않는 이유는?

    • 함수의 값을 말 그대로 'undefined' 값과 'null' 값을 반환하게 해야하기 때문
    • 결국, return undefined, return null을 써줘야하기 때문에 return 문을 쓰지 않고 싶기 때문에 void를 씀
    // void
    // void -> 공허 -> 아무것도 없다
    // void -> 아무것도 없음을 의미하는 타입
    
    function func1 (): string {
      return 'hello';
    }
    
    function fun2(): void {
      console.log('hello');
    }
    
    let a: void;
    // a = 1; 오류
    // a = 'hello'; 오류
    // a = {}; 오류
    a = undefined;
    // a = ull; strictNullCheck = false일 경우 오류 발생하지 않음

✨ Never 타입

  • 불가능한 타입

  • 무한 루프를 도는 함수의 반환값 타입을 어떤걸로 정의해야 할까?

  • 아무값도 반환하지 않으므로 void를 써야할까?

  • 위의 func2 함수를 보면, 반환하는 값 자체가 없이 정상적으로 종료된 것을 볼 수 있지만, func3는 반환할 수 없는 상태여서 애초에 정상적으로 종료가 되지 않는다. (함수가 뭔가를 반환하는 자체가 모순이고 불가능할때 never을 사용)
    e.g) 오류를 던지는 함수

  • never도 변수의 타입을 정의하는데 사용할 수 있는데, void값과 똑같이 어떠한 값에도 오류가 발생하고, undefined에도 오류가 발생함

    • null도 담을 수 없음 (StrickNullChecks 옵션을 false로 지정해도)
    • any타입까지도 담을 수 없음
  • never 타입을 변수의 타입으로 활용하면, 그 어떠한 값도 저장할 수 없는 변수의 타입을 정의할때 사용할 수 있음

    // never
    // never -> 존재하지 않는
    // 불가능한 타입
    
    function func3(): never {
      while (true) {}
    }
    
    function func4(): never {
    throw new Error();
    }
    
    let anyVar: any;
    
    let b: never;
    // b = 1; 오류
    // b = 'hello'; 오류
    // b = {}; 오류
    // b = anyVar; 오류

✨ 타입스크립트 이해

  • 왜 원리까지 이해 해야할까?
    • 문법만 달달 외워서 쓰면 실제로 문제를 해결하기 어려움
    • 이상한 코드들을 만들게 됨

✨ 타입은 집합

  • 타입스크립트가 말하는 타입은 집합임

    • 집합은 동일한 속성과 특징을 갖는 여러개의 원소를 묶어 놓은 단위임
    • number 타입의 집합 안에 위의 여러 값들이 포함될 수 있음
    • 숫자 리터럴 타입(number literal type)도 아래처럼 20이라는 값만 들어올 수 있는 아주 작은 집합이 될 수 있음
    • number literal type 집합은 number 타입의 부분 집합임
    • number literal type이 포함하는 값들은 전부 number type 집합에도 포함되는 값이기 때문
  • 타입스크립트가 말하는 타입이란, 값들을 포함하고 있는 집합임

    • 그러므로, 서로 타입들끼리 부모와 자식 관계를 맺으며 결국 모든 타입들의 관계를 놓고 보면, 타입 계층도로 만들어서 표현할 수 있음
  • 타입스크립트의 타입들이 서로 집합이고, 계층을 이루고 있다는 것을 알고 있으면 타입 간의 호환성을 이해할 수 있음

    let num1: number = 10;
    let num2: 10 = 10;
    
    num1 = num2; // 10을 number에 넣을 수 있음
    num2 = num1; // 오류 발생. number을 10에 넣을 수 없음

  • 다운 캐스팅은 대부분의 상황에 허용되지 않고, 업 캐스팅은 모든 상황에 가능함

✨ 타입 계층도와 함께 기본타입 살펴보기

  • 타입스크립트의 모든 타입은 집합이며, 서로 부모와 자식 관계를 맺고 부모 타입은 슈퍼 타입, 자식 타입은 서브 타입이라고 했음
    • 서브타입의 값을 슈퍼타입의 값으로 취급하는 것 : 업캐스트 (모든 상황에 허용 됨)
    • 슈퍼타입의 값을 서브타입의 값으로 취급하는 것 : 다운캐스트 (대부분의 상황에 허용되지 않음)
  • 타입 계층도

📍 unknown 타입

  • 타입 계층의 최상단에 위치하고 있음

    • 타입스크립트의 모든 타입들의 슈퍼타입임
    • 집합으로 보면, unknown 타입은 '전체 집합'임
    • unknown 타입 변수에는 모든 타입의 값을 할당할 수 있음(= 모든 타입은 unknown 타입으로 업 캐스트 할 수 있음)
      e.g) number 타입의 값을 unknown 타입으로 취급 -> 업 캐스팅
  • 업 캐스팅은 모두 다 허용 -> unknown 타입은 모든 타입의 슈퍼 타입이기 때문에 모든 값을 집어 넣을 수 있음 (계층도를 보면 이해 더 쉬움!!)

  • 그런데, unknown 타입의 값은 any를 제외한 어떤 타입의 변수에도 할당할 수 없음 -> 다운 캐스팅
    e.g) number 타입의 변수에 unknown 값을 넣겠다는 것

  • 결국, unknown 타입의 변수에는 모든 값을 넣을 수는 있지만(업 캐스팅), 반대로 unknown 타입의 값은 어떤 타입의 변수에도 들어갈 수 없음(다운 캐스팅)

      /**
       * Unknown 타입
       */
    
      function unknownExam() {
        let a: unknown = 1;
        let b: unknown = 'hello';
        let c: unknown = true;
        let d: unknown = null;
        let e: unknown = undefined;
        let f: unknown = {};
    
        let unknownVar: unknown;
    
        // let num: number = unknownVar; 오류
        // let str: string = unknownVar; 오류
        // let bool: boolean = unknownVar; 오류
    
      }  
    

📍 never 타입

  • 불가능, 모순을 의미하는 타입

  • nver 타입을 타입 계층도에서 보면, 가장 아래에 위치한 것을 볼 수 있음

    • 모든 타입의 서브타입임 -> 모든 집합의 부분 집합 -> 공집합
  • 반환할 수 있는 값의 종류가 아무 것도 없다는 뜻 = 공집합

  • never 타입은 모든 타입의 서브 타입이기 때문에 어떠한 타입의 변수의 값이 될 수 있음 (업 캐스팅)

  • 반대로, never 타입의 변수에는 어떠한 타입의 값을 넣을 수 없음(다운 캐스팅)

  • 따라서, never 타입은 어떤 값도 저장되어서는 안되는 변수에 활용할 때 좋음 (never 타입에 아무런 값을 저장할 수 없게할 때)

    /**
     * Never 타입
     */
    
    function neverExam() {
    
      function neverFunc(): never {
        while (true) {}
      }
    
      let num: number = neverFunc();
      let str: string = neverFunc();
      let bool: boolean = neverFunc();
    
      // let never1: never = 10; 오류
      // let never2: never = 'string'; 오류
      // let never3: never = true; 오류
    }

📍 void 타입

  • 반환 값이 없는 함수, 즉 return문 자체가 없는 함수의 타입을 명시하는 데 사용

  • undefined 타입과 never 타입의 슈퍼 타입임

    • void 타입에는 undefined, never 이외에 다른 타입의 값을 할당할 수 없음 (업 캐스팅)
      • 함수의 반환값이 undefined가 되어도 된다는 말 (return undefined)
    /**
     * Void 타입
     */
    
    function voidExam() {
      function voidFunc(): void {
        console.log('hi');
        return undefined;
      }
    
      let voidVar: void = undefined;
    }

📍 any 타입

  • any 타입은 계층도 상에서는 unknown 타입의 서브 타입에 위치한 것으로 보이지만, any 타입은 타입 계층도를 완전히 무시함

    • any 타입은 모든 타입의 슈퍼 타입으로 위치하기도 하고, 모든 타입의 서브 타입으로 위치하기도 함 (never 제외)
      e.g) unknown 타입의 값을 any 타입의 변수로 할당 가능 (다운 캐스팅 가능)
      e.g) any 타입의 값을 undefined 타입의 변수로 할당 가능 (다운 캐스팅 가능)
  • any 타입은 자기한테 오는 다운 캐스팅도 되고, 자기가 다운 캐스팅하는 것도 가능 -> 치트키 타입

  • 따라서, 타입 계층도를 완전히 무시하는 타입이라 사용하는것을 권장하지 않는다고 함

  • never 타입의 변수에 any 타입 값을 할당하지 못함!!!!
    e.g) any 타입의 값을 never 타입의 변수로 할당 불가능 (다운 캐스팅)

    • never 타입은 순수한 공집합이기 때문에, 그 어떤 타입도 다운 캐스팅 할 수 없음
    /**
     * Any 타입
     */
    
    function anyExam() {
      let unknownVar: unknown;
      let anyVar: any;
      let undefinedVar: undefined;
      let neverVar: never;
    
      anyVar = unknownVar;
    
      undefinedVar = anyVar;
    
      // neverVar = anyVar; 오류
    }

✨ 타입 호환 표


출처: 한 입 크기로 잘라먹는 타입스크립트

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글