TypeScript enum과 generic에 관하여


🔎 enum

타입스크립트는 숫자와 문자열 기반의 열거형을 제공한다.


숫자 열겨헝

enum Direction {
    Up = 1,
    Down,
    Left,
    Right,
}

Up이 1로 초기화되면 뒤에 따라오는 멤버들은 2부터 차례대로 증가되는 값을 가진다.

초기화를 하지 않는다면 Up은 0부터 시작해서 다음 멤버들은 1부터 증가되는 값을 가진다.


문자열 열거형

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

문자열 열거형은 각 멤버를 초기화해야하며, 자동 증가 기능이 없지만 직렬화에서 이점을 가진다.

예를 들어 숫자만으로 이것이 어떤 의미인지 정보를 제공받기 어렵지만, 문자열 열거형을 이용하면 코드를 실행할 때 유의미하고 읽기 좋은 값을 이용하여 실행할 수 있다.




🔎 제네릭

재사용이 가능한 컴포넌트를 생성하는 주요 도구 중 하나가 제네릭이다.
제네릭을 사용해서 단일타입이 아닌 다양한 타입에서 작동하는 컴포넌트를 작성할 수 있기 때문이다.

function identity<T>(arg: T): T {
    return arg;
}

T는 유저가 준 인수의 타입을 캡처하고 이 정보를 나중에 사용할 수 있게 한다.

위 예제는 T를 반환타입으로 다시 사용하여 타입 정보를 함수의 한쪽에서 다른 한쪽으로 운반할 수 있게끔 했다.

T대신 any를 사용해도 코드에는 오류가 없지만, 타입 정보를 잃는 손해가 발생한다.
반면 제네릭은 어떤 정보도 잃지 않을 수 있다.


변수 작업

function loggingIdentity<T>(arg: T): T {
  console.log(arg.length);
  return arg;
}

인수의 타입이 문자열이 아니기 때문에 length 프로퍼티는 존재하지 않고 오류가 발생된다.


제네릭 제약조건

특정 타입으로 동작하는 제네릭 함수를 만들어 보자.

제네릭 타입이지만 length 프로퍼티를 가지는 타입을 원할 때 제네릭이 어떤 타입이 될 수 있는 지 제약 조건을 나열해줄 수 있다.

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

T는 인터페이스 규약을 따른다면 length 프로퍼티가 있어야 하며 이는 number 값을 가져야 한다.

따라서 T타입의 인수는 .length를 사용해서 길이를 얻을 수 있게 되는 것이다.

만약 loggingIdentity(3); 명령을 주면 numberlength프로퍼티가 없으므로 오류가 발생한다.


객체의 키를 타입의 제약조건으로 설정하기

function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); 
getProperty(x, "m"); 

K는 T의 key로 제약되어 있다.

따라서 mx라는 객체에 존재하지 않는 키이기 때문에 오류가 발생한다.
반면 a는 존재하는 키이기 때문에 정상동작한다.

좋은 웹페이지 즐겨찾기