[TS] enum, keyof, typeof

김채운·2023년 2월 6일
0

Typescript

목록 보기
2/7

enum은 변수들을 하나의 그룹으로 묶고싶을 때 사용한다.
이넘은 특정 값들의 집합을 의미하는 자료형으로서 타입스크립트에서는 문자형 이넘과 숫자형 이넘을 지원한다.

숫자 열거형 (numeric enum)


const enum EDirection {
    Up, // 0
    Down, // 1
    Left,  // 2
    Right,  // 3
}

const num = EDirection.Down;
console.log(num); // 1
  • 값을 따로 정해주지 않으면 초기 값으로 0부터 시작해 1씩 증가한다.

const enum EDirection {
    Up = 3, 
    Down = 4, 
    Left = 5,  
    Right = 6,  
}
  • 초기 값을 정해주면 초기값으로 부터 1씩 증가한다.

const enum EDirection {
    Up = 3, 
    Down = 7, 
    Left = 4,  
    Right = 6,  
}
  • 아니면 이렇게 불규칙하게 지정 해주는 방법도 있음.

리버스 매핑 (reverse mapping)

enum Enum {
  A
}
let a = Enum.A; // 0; 키로 값을 획득 하기
let keyName = Enum[a]; // "A"; 값으로 키를 획득 하기
  • 리버스 매핑은 숫자형 이넘에만 존재하는 특징이다. 에넘의 키(key)로 값(value)를 얻을 수 있고 값(value)로 키(key)를 얻을 수도 있습니다.

문자 열거형 (string enum)


const enum EDirection {
    Up = "up", 
    Down = "down", 
    Left = "left",  
    Right = "right",  
}

const walk = EDirection.Right;
console.log(walk); // 'right'
  • 문자형 이넘은 이넘 값 전부 다 특정 문자 또는 다른 이넘 값으로 초기화 해줘야 한다.
  • 문자형 이넘에는 숫자형 이넘과는 다르게 자동으로 증가해주지는 않는다. 대신 디버깅을 할 때 숫자형 이넘의 값은 가끔 불명확하게 나올 때가 있지만 문자형 이넘은 항상 명확한 값이 나와 읽기 편하다.

❗ enum은 직접 타입으로 사용이 가능하다.

function walk (dir: EDirection) {
    console.log(dir);
} // dir은 EDirection의 Up,Down,Left,Right중 하나여야 된다는 얘기이다.

walk(EDirection.Left); // 2

이넘 활용


// 이넘을 사용해 입력값을 구체적인 값으로 제한할 수 있음.
enum Answer {
    Yes = 'yes',
    No = 'no'
}
 
function askQuestion2(answer: Answer) {
    if (answer === 'yes') {
        console.log('정답입니다');
    }
    if (answer === 'no') {
        console.log('오답입니다')
    }
}
// 이넘에서 제공하는 데이터만 입력받게 된다.
askQuestion2(Answer.Yes);
askQuestion2('yes'); // error

이넘은 입력값을 제한하고 싶을 때 사용한다.

일반 객체로 enum 효과


const ODirection = {
    Up: 0,
    Down: 1,
    Left: 2,
    Right: 3,
} as const;
  • 저 객체에서 as const를 빼고 커서를 올리면 저 변수들 타입이 다 number로 뜬다 근데 여기서 정확히 0,1,2,3처럼 정확한 값이 나오길 바라면

const ODirection: {Up:0, Down:1, Left:2, Right:3} = {
    Up: 0,
    Down: 1,
    Left: 2,
    Right: 3,
};
  • 이렇게 해줄 수도 있지만, 나는 이 값을 상수로 쓰겠다 하면 편한 방법으로는 위에 처럼 as const를 붙여주면 돼. 그래서 다시 커서 올려보면 상수로 정확히 타입이 나온다. 여기서는 readonly까지 붙어서 나오는데, 이 읽기전용은 수정을 못한다.

keyof, typeof

객체를 타입으로 사용하기 위해선 typeof 와 keyof 파라미터를 사용해야 한다

const obj = { 
  a:'123', 
  b: 'hello', 
  c:'world' 
}

type key = keyof obj; // error
type key = keyof typeof obj;
// type key = "a"|"b"|"c"

type key = typeof obj
// const obj: {a: string, b: string, c: string}

이 객체에서 key값인 a,b,c만 꺼내오고 싶다면 'type key = keyof obj;' 이렇게 할 수 있겠지만 이렇게 하면 error가 뜬다. 왜냐? obj는 JS 값인데 type으로 쓰려고 하기 때문이다. 이 때, 앞에 typeof를 붙여준다. 이렇게 값을 타입으로 쓰고 싶을 때 typeof를 사용한다.
그럼 typeof obj는, const obj: {a: string, b: string, c: string} 이렇게 타입이 정의가 되는거지. 그런데 여기서 key들만 뽑고 싶다면 그럴 때 쓰는 게 keyof다. 그래서 최종적으로
type key = keyof typeof obj;는 type key = "a"|"b"|"c" 가 되는 거다.


const ODirection = {
    a:'123', 
    b: 'hello', 
    c:'world'
} as const;

type value = typeof ODirection[keyof typeof ODirection]; // 이렇게 하면 value들만 다 가져오고 싶다는 거다.

function run(dir: value) {
   console.log(dir);
}

run(ODirection.c); // world

0개의 댓글