JNU-econovation / hotsix-study

에코노베이션 타입스크립트 스터디
5 stars 7 forks source link

[01/17] 4장 #75

Open 2yunseong opened 9 months ago

2yunseong commented 9 months ago

우아한 3장

difference between extend and Intersect

intersect와 extends의 차이는, extends 는 호환되지 않는 타입에 대해서는 오류를 발생 시킨다.

interface Parent {
    a: number;
}

interface Child extends Parent { // Error: ts2430
    a: string;
}

비슷하게 interface는 선언 병합이라는 것으로도 흉내낼 수 있다.

interface Parent {
  a:number;
}

interface Parent {
  b:number;
}

하지만 intersect는 never로 평가한다.

/* 각 타입의 a의 타입이 number, string 일 때 */
type Merge = Parent & Child; /* {  a:never  } */

diferrence between added property and extend

// case1. 타입 속성 추가
interface Menu {
  name:string;
    image:string;
    gif?:string;
    text?:string;
}
// case2. 타입 확장
interface Menu {
    name:string;
    image:string;
}

interface SpecialMenu extends Menu {
    gif:string;
}

interface PackageMenu extends Menu {
    text:string;
}

case1. add property

추가로 접근할 때는 SpecialMenu처럼 사용하고 싶을 때는 항상 타입 좁히기 를 해주어야한다.

if(!menu.gif) {
    // gif 속성이 있는 Menu를 사용할 수 있다.
}

case2. extends

물론 타입 확장을 사용해도 특정 타입 처럼 사용할 때는 좁혀야 하긴 하지만, 특정된 타입만 사용할 때는 특정 타입으로 선언할 수 있다는 장점이 있다.

const specialMenus:SpecialMenu[] = [{ ... }] // SpecialMenu의 속성을 바로 사용할 수 있다.

specialMenus[0].gif // OK!

type narrowing

type predicates(타입 명제)

Discriminated Unions

interface TypeError {
    eType: 'TYPE';
    errMsg: string;
    line: number;
}

interface NetworkError {
    eType: 'NETWORK';
    errMsg:string;
    line: number;
    httpStatus: number;
}

// discriminat로 판별할 수 있는 Union이 된다.
type MyError = TypeError | NetworkError ;

주의사항

쉽게 말해, 식별할 수 있는 단 한가지의 값으로 판별자를 사용하자.

Exhaustiveness Checking

모든 케이스를 작성해주지 않는다면, params에 never가 아닌 string이 들어가므로 옳지않다.

따라서 모든 ProductPrice에 대한 대응을 해주어야하고, 그 의미에 맞게 switch문으로 변경해보았다.

type ProductPrice = "10000" | "20000" | "5000";

const exhaustiveCheck = (params:never):never => {
    throw new Error("존재하지 않는 상품권 수량입니다.")
};

const getProductName = (productPrice:ProductPrice): string => {
    switch(productPrice) {
        case "10000":
            return "배민 상품권 일만원";
        case "20000":
            return "배민 상품권 이만원";
        case "5000":
            return "배민 상품권 오천원";
        default:
            return exhaustiveCheck(productPrice);
    }
}

이야기