- Enum
- 사용하는 이유
- 숫자형
- 문자형
- 사용 안 하는 이유
- Union & Intersection Type
- Literal Type의 Union Type
- Intersection Type
- 주의할 점
1. Enum
1-0) 사용하는 이유
그림과 같이, property의 값을 한정 짓기 위해 열거형 Enum을 사용한다
이름 있는 상수들, 혹은 연관된 아이템을 묶어서 표현할 수 있다
1-1) 숫자형
초기 값을 주면 초기 값부터 차례로 1씩 증가하는 auto-incrementing; 자동 증가 기능
enum Direction {
Zero = 1,
One,
Two,
Three
}
// Zero - 1
// One - 2
// Two - 3
// Three - 4
// 초기화 안 하면 0부터 시작
enum의 key로 value를 얻을 수 있고, value로 key를 얻을 수 있는 Reverse Mapping
enum Enum {
A
}
let a = Enum.A; // 0; 키로 값을 획득 하기
let keyName = Enum[a]; // "A"; 값으로 키를 획득 하기
1-2) 문자형
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
1-a) 사용 안 하는 이유
위 코드 캡쳐본을 보면 알다시피, Javascript로는 IIFE(즉시 실행 함수 표현)을 사용한다
이는 Rollup과 같은 번들러가 섣불리 Tree-shaking을 하지 않아,
하나의 변수만 사용할 때에도 모든 코드를 불러오게 된다
이를 해결하기 위한 const enum이 존재한다
하지만 선언 코드와 사용 코드가 다른 모듈에 있다면,
선언부의 모듈까지 실행해야 하는 단점이 존재한다 (--isolatedModules 가 켜져 있으면 아예 불가능)
또한 babel 에서 추가로 플러그인을 설치해야 한다
그래서 우리는 Union Type을 주로 사용하는 것이 좋다
(enum에서 우리는 keyof 대신 keyof typeof 를 사용해야 한다)
const로 선언했다 할지라도 객체이기 때문에 바뀔 수 있는데,
as const 사용함으로써 readonly 를 강제하는 효과를 낳는다
2. Union & Intersection Type
2-1) Literal Type의 Union Type
// any를 사용하는 경우
function getAge(**age: any**) {
age.toFixed();
// 에러 발생
return age;
}
// 유니온 타입을 사용하는 경우
function getAge(**age: number | string**) {
// 타입 좁히기(Type Narrowing)
if (typeof age === 'number') {
age.toFixed();
// 정상 동작, 숫자 관련된 API를 쉽게 자동완성 할 수 있음
return age;
}
if (typeof age === 'string') {
return age;
}
//return new TypeError('age must be number or string');
}
2-2) Intersection Type
interface Person {
name: string;
age: number;
}
interface Developer {
name: string;
skill: number;
}
type Capt = Person & Developer;
// -->
// {
// name: string;
// age: number;
// skill: string;
// }
2-a) 주의할 점
Union - Intersection을 단순하게 OR - AND 라고 생각하면 논리적인 오류가 생길 수 있다
다음 코드를 보자
interface Person {
name: string;
age: number;
}
interface Developer {
name: string;
skill: string;
}
function introduce(someone: Person | Developer) {
someone.name; // O 정상 동작
someone.age; // X 타입 오류
someone.skill; // X 타입 오류
}
이와 같이, property들을 OR, 합집합 마냥 쓸 수 있는 것이 아니다
introduce의 someone 은 Person인지, Developer인지 모르기 때문에, 공통의 property에만 접근할 수 있다
이를 해결하기 위해, 우리는 타입 가드(Type Guard), 타입 좁히기(Type Narrowing) 작업을 필히 해주어야 한다
function introduce(someone: Person | Developer) {
someone.name; // O 정상 동작
if (isPerson(someone)) {
someone.age; // O 정상 동작
} else if (isDeveloper(someone)) {
someone.skill; // O 정상 동작
}
}
// ---
function isPerson(someone: Person | Developer): someone is Person {
return "age" in someone
}
function isDeveloper(someone: Person | Developer): someone is Developer {
return "skill" in someone
}
'JS, TS' 카테고리의 다른 글
[Javascript] Map & Set 객체 살펴보기 (2) | 2022.05.30 |
---|---|
[Javascript] call & apply 로 this 특정시키기 (0) | 2022.05.11 |
[Javascript] Event Delegation / 이벤트 위임 (0) | 2021.10.10 |
[Javascript] Promise와 Async / Await (0) | 2021.09.05 |
[Javascript][ES6] 화살표 함수 (Arrow Function)와 템플릿 리터럴 (Template Literals) (0) | 2021.09.05 |