Typescript Generics와 Keyof, Mapped Types 사용해보기

타입스크립트에서 제네릭, Mapped Types을 사용해보고, keyof 키워드는 어느 상황에서 사용할 수 있을지 사용해보았다.

interface dynamic {
    [key: number] : string,
}
const keys: dynamic = {1: 'one', 2: 'two'};

타입스크립트에서는 위처럼 동일한 타입의 key-value값들을 갖는 객체를 정의할 수 있다.

다만, 이 경우 value의 타입은 맨 처음의 선언한 것에서 바뀔 수 없는 단점이 있다.

제네릭을 사용하여 더 확장성있게 코드를 작성할 수 있다.

interface dynamic<T> {
    [key: number] : T,
}
const str: dynamic<string> = {1: 'one', 2: 'two'};
const num: dynamic<number> = {1: 100, 2: 200};

함수를 사용할 때도 제네릭을 사용할 수 있다.

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

consoleType<string>("hi");
consoleType<number>(123);

keyof 키워드는 객체의 key값들을 타입으로 만들 수 있게 해준다.

interface t {
    name: string,
    100: number
}

type tType = keyof t;
const nickname: tType = 'name';
const age: tType = 100;
const score: tType = 20; // ERROR

위의 인터페이스는 각각 name과 100을 key값으로 가지는 객체의 타입을 선언하고 있다.

이때 keytype으로 인터페이스의 키값들을 가져올 수 있고, name이나 100만을 가지는 타입 변수를 만들 수 있다.

interface p {
    [key: string]: number,
}
type pType = keyof p;
const variable: pType = 'apple'

위와 같이 mapped type으로 생성된 타입에서는 키 값에 할당된 변수의 타입을 가져오기에 위에서 variable은 string의 값을 가지는 변수가 될 수 있다.

keytype을 응용하여 다음과 같은 코드를 작성할 수 있다.

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};

위의 타입 코드는 타입스크립트 공식문서에서 확인할 수 있는 코드인데, 언뜻 보기에 바로 이해하기가 쉽지 않다.

말로 풀어 설명하자면, Type을 순회하면서 keyof로 key값을 가져온다. 그리고 그 가져온 key값에 제네릭으로 받은 새로운 value 타입을 할당하는 방식이다.

실제 사용 예를 보면 다음과 같다.

interface User {
    name: string,
    age: number,
    job: boolean,
}

type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};

const variable: OptionsFlags<User> = {
    name: false,
    age: true,
    job: false,
};

요약하자면, 같은 키값을 가지지만, value의 타입은 다른 객체에 대한 타입을 생성할 수 있는 것이다.

 

 

https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html

 

Documentation - Mapped Types

이미 존재하는 타입을 재사용해서 타입을 생성하기

www.typescriptlang.org