[TS] 제네릭 타입 변수 응용

TIL

제네릭 함수 활용 사례

사례 1: 여러 개의 타입 변수

두 값의 위치를 바꾸는 swap 함수를 만들어 보자.

function swap(a: any, b: any) {
  return [b, a];
}

const [a, b] = swap(1, 2);

any타입을 사용하면 타입 안정성이 보장되지 않는다.

 

2개의 타입 변수가 필요한 상황이라면 다음과 같이 T, U 처럼 여러 개의 타입 변수를 사용할 수 있다.

function swap<T, U>(a: T, b: U) {
  return [b, a];
}

const [a, b] = swap("1", 2);

위 코드에서 T는 string 타입으로, U는 number 타입으로 추론된다.

반환값은 [U, T] 즉, [number, string] 튜플 타입이 된다.

 

사례 2: 배열 요소 타입 추론

배열의 첫 번째 요소를 반환하는 함수를 만들어보자.

function returnFirstValue(data: any) {
  return data[0];
}

let num = returnFirstValue([0, 1, 2]);
let str = returnFirstValue([1, "hello", "mynameis"]);

 

다양한 배열 타입을 인수로 받는 제네릭 함수는 다음과 같이 만들 수 있다.

function returnFirstValue<T>(data: T[]) {
  return data[0];
}

let num = returnFirstValue([0, 1, 2]); // number
let str = returnFirstValue([1, "hello", "mynameis"]); // number | string

함수 매개변수 data의 타입을 T[]로 설정했기 때문에 배열이 아닌 값은 인수로 전달할 수 없으며, 배열을 인수로 전달하면 T는 배열의 요소 타입으로 추론된다.

첫 번째 호출에서는 number[] 타입의 값을 전달했으므로 T는 number 타입으로 추론되며, 반환값 타입도 number가 된다.

두 번째 호출에서는 (number | string)[] 타입의 값을 전달했으므로 T는 number | string 타입으로 추론되며, 반환값 타입도 number | string가 된다.

 

사례 3: 첫 번째 요소 타입만 추론

위 사례에서 반환값의 타입을 배열의 첫 번째 요소 타입으로 정확히 지정하려면 튜플 타입과 나머지 파라미터를 이용하면 된다.

function returnFirstValue<T>(data: [T, ...unknown[]]) {
  return data[0];
}

let str = returnFirstValue([1, "hello", "mynameis"]); // number

함수 매개변수의 타입을 튜플 타입 [T, ...unknown[]]로 정의하면 첫 번째 요소의 타입은 T, 나머지 요소는 길이와 타입에 상관없이 받을 수 있다.

함수를 호출하고 [1, "hello", "mynameis"] 같은 배열을 인수로 전달하면 T는 첫 번째 요소의 타입인 number가 되며, 반환값 타입도 number가 된다.

 

사례 4: 타입 변수 제한하기

타입 변수를 제한한다는 것은 함수 호출 시 인수로 전달할 수 있는 값의 범위에 제한을 두는 것을 의미한다.

function getLength(data: any) {
  return data.length;
}

let var1 = getLength([1, 2, 3]);
let var2 = getLength("12345");
let var3 = getLength({ length: 10 });
let var4 = getLength(10); // 런타임 오류

any 타입을 사용하면 length 프로퍼티가 없는 값도 전달할 수 있어 위험하다.

 

타입 변수를 length 프로퍼티를 갖는 타입으로 제한해보자.

function getLength<T extends { length: number }>(data: T) {
  return data.length;
}

getLength("123");            // ✅
getLength([1, 2, 3]);        // ✅
getLength({ length: 1 });    // ✅
getLength(10);               // ❌

타입 변수를 제한할 때는 extends 키워드를 사용한다. T extends { length: number }로 정의하면 T는 { length: number } 객체 타입의 서브 타입이 된다.

즉, T는 무조건 number 타입의 length 프로퍼티를 가지고 있어야 한다. 따라서 문자열, 배열, length 프로퍼티를 가진 객체는 전달할 수 있지만, 숫자처럼 length가 없는 값은 전달할 수 없다.

'TIL' 카테고리의 다른 글

[TS] 제네릭 인터페이스와 타입 별칭  (0) 2025.11.04
[TS] map, forEach 메서드 타입 정의하기  (0) 2025.11.04
[TS] 제네릭  (0) 2025.11.04
[CS50] 컴퓨팅 사고 - 2진법  (0) 2025.11.03
[TS] 클래스와 접근제어자 사용 연습  (0) 2025.11.03
'TIL' 카테고리의 다른 글
  • [TS] 제네릭 인터페이스와 타입 별칭
  • [TS] map, forEach 메서드 타입 정의하기
  • [TS] 제네릭
  • [CS50] 컴퓨팅 사고 - 2진법
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    문자열
    javascript
    Spa
    타입 좁히기
    자료구조
    Next.js
    배열
    바닐라 자바스크립트
    algorithm
    ai 감성 일기장
    앱 라우터
    클래스
    인터페이스
    useState
    C
    cs50
    함수 타입
    트러블 슈팅
    emotion diary
    Pages Router
    memory
    App Router
    Trouble Shooting
    CS
    react
    generic
    제네릭
    알고리즘
    typescript
    페이지 라우터
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
[TS] 제네릭 타입 변수 응용
상단으로

티스토리툴바