제네릭 타입을 선언해서, 문자열 리터럴 타입으로 추론하도록 하고 싶은 상황이 발생해서 이것저것 시도하다가 찾은 방법을 정리해봅니다.
세 가지 경우를 예시로 정리해보려고 합니다.
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 |