inblog logo
|
Typescript Study

    [Learning Typescript] Ch.3 유니언과 리터럴

    Typescript
    Dragon C's avatar
    Dragon C
    Nov 22, 2023
    [Learning Typescript] Ch.3 유니언과 리터럴
    Contents
    3.1 유니언 타입3.1.1 유니언 타입 선언3.1.2 유니언 속성3.2 내로잉3.2.1 값 할당을 통한 내로잉3.2.2 조건 검사를 통한 내로잉3.2.3 typeof 검사를 통한 내로잉3.3 리터럴 타입3.3.1 리터럴 할당 가능성3.4 엄격한 null 검사3.4.2 참 검사를 통한 내로잉3.5 타입 별칭3.5.1 타입 별칭은 자바스크립트가 아닙니다3.5.2 타입 별칭 결합
    • 타입스크립트가 값을 바탕으로 추론을 수행하는 두 가지 핵심 개념 “유니언”과 “내로잉”

    • 유니언(union): 값에 허용된 타입을 두 개 이상의 가능한 타입으로 확장하는 것

    • 내로잉(narrowing): 값에 허용된 타입이 하나 이상의 가능한 타입이 되지 않도록 좁히는 것

    3.1 유니언 타입

    • “이거 혹은 저거”와 같은 타입을 유니언 이라고 함

    • 값의 정확한 타입은 모르지만 두 개 이상의 옵션 중 하나임을 알고 있는 경우 코드를 처리함

    • 타입스크립트 구문에서는 값이나 구성 요소 사이에 | 연산자를 사용하여 유니언 타입을 나타냄

    // let mathematician: string | undefined
    let mathematician = Math.random() > 0.5 ? undefined : "Mark Goldberg";

    3.1.1 유니언 타입 선언

    • 변수의 초깃값이 있는 경우에도 변수에 대한 명시적 타입 애너테이션을 제공하는 것이 유용할 때 유니언 타입을 사용함

      // 초깃값이 null이지만 잠재적으로 string이 될 수 있음
      let thinker: string | null = null;
      if (Math.random() > 0.5) {
      	thinker = "Susanne Langer";
      }

    3.1.2 유니언 속성

    • 값이 유니언 타입일 때 타입스크립트는 유니언으로 선언한 모든 가능한 타입에 존재하는 멤버 속성에만 접근할 수 있음. 그렇지 않을 경우 타입 검사 오류가 발생함

    • 예) number | string 타입인 변수가 있을 때 해당 변수에 대해 두 개의 타입에 존재하는 toString()은 사용할 수 있지만, toUpperCase()와 toFixed()는 사용할 수 없음. toUpperCase()는 number 타입에 없고, toFixed()는 string 타입에 없기 때문

    • 이는 안전 조치에 해당하는 것으로, 객체가 어떤 속성을 포함한 타입으로 확실하게 알려지지 않은 경우 해당 속성이 존재하지 않을 수도 있기에 이러한 조치를 함

    • 여러 타입 중 하나에 대한 속성을 사용하려면 코드에서 구체적인 타입을 알려주어야 하며 이를 내로잉이라고 함

    3.2 내로잉

    • 값이 이전에 유추된 것보다 더 구체적인 타입임을 코드에서 유추하는 것을 내로잉이라고 함

    • 타입을 좁히는 데 사용할 수 있는 논리적 검사를 타입 가드(type guard)라고 함

    3.2.1 값 할당을 통한 내로잉

    • 변수에 값을 직접 할당하면 타입스크립트는 변수의 타입을 할당된 값의 타입으로 좁힘

    • number | string 타입으로 명시한 변수에 string 값을 할당하면 값 할당 내로잉이 작동함

    • 이후에는 number, string 중 하나의 값을 받을 수 있더라도 처음에는 할당된 타입으로 시작함을 이해함

    3.2.2 조건 검사를 통한 내로잉

    • 변수가 알려진 값과 같은지 확인하는 if문을 통해 변수의 값을 좁힐 수 있음

    let scientist = Math.random() > 0.5 ? "Rosalind Franklin" : 51;
    
    if (scientist === "Rosalind Franklin") {
    	scientist.toUpperCase(); // Ok
    }
    
    scientist.toUpperCase(); // Error

    3.2.3 typeof 검사를 통한 내로잉

    • typeof 연산자를 사용하여 변수의 값이 특정 타입에 해당하는지 확인할 수 있음

    let researcher = Math.random() > 0.5 ? "Rosalind Franklin" : 51;
    
    if (typeof researcher === "string") {
    	researcher.toUpperCase();
    }
    
    typeof researcher === "string" ? researcher.toUpperCase() : researcher.toFixed()

    3.3 리터럴 타입

    구체적인 버전의 원시 타입인 “리터럴 타입”

    • 원시 타입 값 중 어떤 것이 아닌 특정 원싯값으로 알려진 타입

    • 변수를 const로 선언하고 직접 리터럴 값을 할당할 경우 타입스크립트는 해당 변수를 할당된 리터럴 값으로 유추함

      const philosopher = "Hypatia"; // const philosopher: "Hypatia"
    • 각 원시 타입은 해당 타입이 가질 수 있는 가능한 모든 리터럴 값의 전체 조합

      - boolean: true | false
      - null과 undefined: 둘 다 자기 자신, 즉, 오직 하나의 리터럴 값만 가짐
      - number: 0 | 1 | 2 | 3 | …… | 0.1 | 0.2 | ….
      - string: “” | “a” | “b” | “c” | …… | “aa” | “ab” | “ac” | …

    3.3.1 리터럴 할당 가능성

    • 0과 1처럼 동일한 원시 타입일지라도 서로 다른 리터럴 타입은 서로 할당할 수 없음

      let specificallyAda: "Ada";
      
      specificallyAda = "Ada"; // Ok
      
      specificallyAda = "Byron" // Error: Type '"Byron"' is not assignable to type '"Ada"'.

    3.4 엄격한 null 검사

    • 타입스크립트는 “십억 달러의 실수(The Billion-Dollar Mistake)”를 바로잡기 위해 엄격한 null 검사(strict null checking)를 허용하며 이는 최신 프로그래밍 언어의 큰 변화 중 하나임

    • 3.4.1 십억 달러의 실수

      저는 이를 십억 달러의 실수라고 부릅니다. 1965년, null 참조의 발명으로 수많은 오류, 취약성 및 시스템 충돌이 발생했으며 지난 40년 동안 십억 달러의 고통과 피해를 입었을 것입니다. - 토니 호어(Tonny Hoare), 2009
    • ‘십억 달러의 실수’는 다른 타입이 필요한 위치에서 null 값을 사용하도록 허용하는 많은 타입 시스템을 가리키는 업계 용어임

    • 엄격한 null 검사가 없는 언어에서는 다음과 같이 string 타입 변수에 null을 할당하는 것이 허용됨

      const firstName: string = null;
    • 타입스크립트 컴파일러는 실행 방식을 변경할 수 있는 다양한 옵션을 제공함(13장)

    • 가장 유용한 옵션 중 하나인 strictNullChecks는 엄격한 null 검사를 활성화할지 여부를 결정함

      let nameMaybe = Math.random() > 0.5 ? "Tony Hoare" : undefined;
      nameMaybe.toLowerCase();
      /* 엄격한 null 검사가 비활성화된 경우 - 오류로 판단하지 않음
      Potential runtime error: Cannot read property 'toLowerCase' of undefined.
      */
      
      /* 엄격한 null 검사가 활성화된 경우
      Error: Object is possibly 'undefined'.
      */

    3.4.2 참 검사를 통한 내로잉

    • 타입스크립트는 잠재적인 값 중 truthy로 확인된 일부에 한해서만 변수의 타입을 좁힐 수 있음

    • 다음 코드에서 geneticist는 string | undefined 타입이며 undefined는 항상 falsy이므로 타입스크립트는 if문의 코드 블록에서는 geneticist가 string 타입이 되어야 한다고 추론할 수 있음

      let geneticist = Math.random() > 0.5 ? "Barbara McClintock" : undefiend;
      
      if (geneticist) {
      	geneticist.toUpperCase(); // Ok: string
      }
      
      geneticist.toUpperCase(); // Error: Object is possibly 'undefined'.
    • 논리 연산자 &&와 ?는 참 여부를 검사하는 일도 잘 수행하지만 참 확인 외에 다른 기능은 제공하지 않음

    • string | undefined 값에 대해 알고 있는 것이 falsy라면, 그것이 빈 문자열인지 undefined인지는 알 수 없음

      geneticist && geneticist.toUpperCase(); // Ok: string | undefiend
      geneticist?.toUpperCase(); // Ok: string | undefiend

    3.4.3 초깃값이 없는 변수

    • 자바스크립트에서 초깃값이 없는 변수는 기본적으로 undefined가 됨

    • 값이 할당되기 전에 속성 중 하나에 접근하려는 것처럼 해당 변수를 사용하려고 시도할 경우 오류 메시지가 나타남

    • 변수 타입에 undefined가 포함되어 있는 경우에는 오류가 보고되지 않음

      let mathematician: string;
      
      mathematician?.length;
      // Error: Variable 'mathematician' is used before being assigned.
      
      let mathematician: string | undefined;
      
      mathematician?.length; // Ok

    3.5 타입 별칭

    • 타입스크립트에는 재사용하는 타입에 더 쉬운 이름을 할당하는 타입 별칭(type alias)이 있음

    • type 새로운 이름 = 타입 형태를 갖음

      type RawData = boolean | number | string | null | undefined;
      
      let rawDataFirst: RawData;
      let rawDataSecond: RawData;

    3.5.1 타입 별칭은 자바스크립트가 아닙니다

    • 타입 별칭은 애너테이션처럼 자바스크립트로 컴파일되지 않음

    • 위의 코드는 다음과 같이 자바스크립트로 컴파일 됨

      let rawDataFirst;
      let rawDataSecond;
    • 타입 시스템에만 존재하므로 런타임 코드에서는 참조할 수 없음

      type SomeType = string | undefined;
      
      console.log(SomeType);
      // Error: 'SomeType' only refers to a type, but is being used as a value here.

    3.5.2 타입 별칭 결합

    • 타입 별칭은 다른 타입 별칭을 참조할 수 있음

      type Id = number | string;
      
      // IdMaybe 타입은 다음과 같음: number | string | undefined | null
      type IdMaybe = Id  | undefined | null;

    Share article

    Typescript Study

    RSS·Powered by Inblog