/* 각 타입의 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
런타임에서도 타입을 안전하게 사용하는 방법을 알아야 한다. (컴파일 해도 타입 정보가 사라지지 않는 법을 강구해야 한다.)
원시타입을 추론할 때는 typeof를 사용할 수 있다.
원시타입이 아닌 경우에는 typeof는 생각과 다르게 동작할 수 있으니 주의해야 한다.
인스턴스화된 객체를 추론할 때는 instanceof 연산자를 활용할 수 있다.
객체에 속성이 있는지 없는지를 구분하려면 in 연산자를 활용할 수 있다.
유니온 타입을 좁힐 때 유용하다
type predicates(타입 명제)
타입 좁히기를 할 때, 스코프를 좁히기 위한 조건을 함수화해 사용하는 것
is 키워드 사용
parameter is return value 로 사용
Discriminated Unions
태그된 유니온(Tagged Union)이라고도 불림
보통 유니온 타입의 원소에 식별할 수 있는 판별자(discriminant)를 넣음
판별자는 서로 다르므로 타입 좁히기 시 유용하게 사용가능
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);
}
}
이야기
각 타입 좁히기의 방법을 어떤 상황에 적용하면 좋을 지, 또는 적용되어 있는지 같이 이야기 해봐요
우아한 3장
difference between extend and Intersect
intersect와 extends의 차이는, extends 는 호환되지 않는 타입에 대해서는 오류를 발생 시킨다.
비슷하게 interface는 선언 병합이라는 것으로도 흉내낼 수 있다.
하지만 intersect는 never로 평가한다.
diferrence between added property and extend
case1. add property
추가로 접근할 때는 SpecialMenu처럼 사용하고 싶을 때는 항상 타입 좁히기 를 해주어야한다.
case2. extends
물론 타입 확장을 사용해도 특정 타입 처럼 사용할 때는 좁혀야 하긴 하지만, 특정된 타입만 사용할 때는 특정 타입으로 선언할 수 있다는 장점이 있다.
type narrowing
type predicates(타입 명제)
parameter
isreturn value
로 사용Discriminated Unions
주의사항
쉽게 말해, 식별할 수 있는 단 한가지의 값으로 판별자를 사용하자.
Exhaustiveness Checking
모든 케이스를 작성해주지 않는다면, params에 never가 아닌 string이 들어가므로 옳지않다.
따라서 모든 ProductPrice에 대한 대응을 해주어야하고, 그 의미에 맞게 switch문으로 변경해보았다.
이야기