제네릭 타입을 선언해서, 문자열 리터럴 타입으로 추론하도록 하고 싶은 상황이 발생해서 이것저것 시도하다가 찾은 방법을 정리해봅니다.
세 가지 경우를 예시로 정리해보려고 합니다.
1) 함수에 단일값을 받는 경우
2) 함수에 배열 한 개를 받기
3) 함수에 배열 한 개를 받되, 제네릭 타입을 문자열 타입으로 제한하는 경우
1) 함수에 단일값을 받는 경우
// 단일값
function getValue<T>(param: T) {
return param
}
const v1 = getValue('string') // 'string' 타입
const v2 = getValue('ABC') // 'ABC' 타입
단일값을 제네릭으로 지정한 경우, 문자열 리터럴 타입으로 타입 추론을 잘하고 있습니다.
2) 함수에 배열 한 개를 받는 경우
function getArray<T>(...params: T[]) {
return [...params];
}
const a1 = getArray('string1', 'string2', 'string3'); // string[] 타입으로 추론
const a2 = getArray('A' as const, 'B' as const, 'C'); // string[] 타입으로 추론
const a3 = getArray('A' as const, 'B' as const, 'C' as const); // ('A' | 'B' | 'C')[] 타입으로 추론
배열값을 제네릭으로 지정하면, 문자열 값을 넘기면 리터럴 타입이 아닌 문자열(string) 타입으로 추론합니다.
배열 요소의 공통적인 타입을 파악해서, 그 타입으로 추론하는 듯 합니다.
함수 인자에 상수 문자열을 넘겨줘도, 한 개가 문자열 타입이면, 문자열 타입으로 추론합니다.
모든 인자를 상수 문자열로 넘겨줘야, 문자열 리터럴 타입으로 추론하기 시작합니다.
그런데 문자열 리터럴 타입으로 만들기 위해서는 인자 하나하나에 as const
를 붙여줘야 합니다.
개발자 입장에서 많이 귀찮을 수 있습니다.
그래서, 다른 방법이 있는지 또 찾아봤습니다.
3) 함수에 배열 한 개를 받되, 제네릭 타입을 문자열 타입으로 제한
function getEnumArray<T extends string>(...params: T[]) {
return [...params];
}
const e1 = getEnumArray('string1', 'string2', 'string3'); // ('string1' | 'string2' | 'string3')[] 타입으로 추론
const e2 = getEnumArray('A' as const, 'B' as const, 'C'); // ('A' | 'B' | 'C')[] 타입으로 추론
const e3 = getEnumArray('A' as const, 'B' as const, 'C' as const); // ('A' | 'B' | 'C')[] 타입으로 추론
제네릭 인자 T를 문자열(string) 타입으로 제한하면, 이제야 문자열 리터럴 타입으로 잘 추론하기 시작합니다.
위의 예시에서 e2, e3의 경우 인자 일부 또는 전체에 as const
를 붙였는데, as const
를 빼도 문자열 리터럴 타입으로 추론해줍니다 :)
Typescript 공식 홈페이지의 Playground에서 예제 코드를 테스트해보았는데요.
아래 링크에서 예제 코드를 확인해보실 수 있습니다.
TypeScript Playground에서 테스트 해본 예제 코드
'TypeScript' 카테고리의 다른 글
[Typescript] 객체 전개 연산자(Object Spread)에 객체 외에 다른 타입을 넘긴다면? (1) | 2024.01.21 |
---|---|
[Typescript] 자료구조 : 큐 (Queue) (0) | 2023.02.22 |
[Typescript] 자료구조 : 스택 (Stack) (0) | 2023.02.22 |
[Typescript] 자료구조 : 이중 연결 리스트 (doubly-LinkedList) (0) | 2023.02.19 |
[Typescript] 자료구조 : 단방향 연결 리스트 (Singly-LinkedList) (0) | 2023.02.18 |