Frontend/TypeScript

TypeScript Generic

개발자의 첫 걸음 2025. 11. 21. 18:00

안녕하세요. 오늘은 타입스크립트 제네릭(Generic)에 대해 알아볼게요.

 

 

 

제네릭(Generic)

 

제네릭은 "한 번 만든 코드로 여러 타입을 다루는 기술"이에요.

 

즉, 코드를 재사용하면서도 타입 안정성을 유지할 수 있게 해 줘요.

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

generic<string>("안녕");
generic<number>(123);

<T>는 “타입 변수(type variable)”로, 함수를 호출할 때 타입을 정할 수 있어요.

 

제네릭은 여러 타입 변수를 사용할 수 있는데요.

function pair<T, U>(first: T, second: U): [T, U] {
  return [first, second];
}

let pair1 = pair<string, number>("안녕", 123);
console.log(pair1); // ['안녕', 123]

T, U 등은 타입 자리 표시자 (Type Placeholder)에요. 어떤 타입이든 호출할 때 지정 가능해요.

 

다음은 제네릭 활용한 예시 코드들을 예시로 간단하게 설명드릴게요.

 

 

 

1. 제네릭 함수 활용

function genericFunc<T>(args: T[]): T[] {
  console.log(`배열의 길이: ${args.length}`);
  return args;
}

let result = genericFunc<boolean>([true, false, true]);
// 배열의 길이: 3
// 반환값: [true, false, true]

 

 

2. 제네릭 인터페이스

interface IGeneric<T> {
  (key: T): T;
}

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

let myExample: IGeneric<number> = example;
console.log(myExample(5)); // 5

// 함수 타입을 인터페이스로 지정하고, 타입을 나중에 정할 수 있음.

 

 

3. 제네릭 클래스

class GenericClass<T> {
  value: T;
  add: (x: T, y: T) => T;

  constructor(value: T, addFunc: (x: T, y: T) => T) {
    this.value = value;
    this.add = addFunc;
  }
}

let myClass = new GenericClass<number>(0, (x, y) => x + y);
console.log(myClass.add(4, 6)); // 10

 

 

4. 제네릭 제약 조건(extends)

 

제네릭 타입을 특정 조건으로 제한할 수도 있어요.

interface ILength {
  length: number;
}

function constraints<T extends ILength>(arg: T): void {
  console.log(arg.length);
}

constraints("안녕하세요"); // 5
constraints({ length: 10, value: "test" }); // 10

// T extends ILength → “T는 반드시 length 속성을 가져야 한다.”

 

 

5. keyof 연산자

 

객체의 속성 이름이 타입으로 추출해요.

type Type = { name: string; age: number; };
type Union = keyof Type; // "name" | "age"

 

 

6. 조건부 타입

 

타입에 조건을 걸어 분기할 수 있어요.

type Check<T> = T extends string ? "String" : "Not a String";

let a: Check<string> = "String";
let b: Check<number> = "Not a String";

// 실행 예시
function checkType<T>(value: T): Check<T> {
  return typeof value === "string"
    ? ("String" as Check<T>)
    : ("Not a String" as Check<T>);
}

console.log(checkType("문자열")); // String
console.log(checkType(500));      // Not a String

 

 

마지막으로 제네릭에 대한 핵심 요약표예요.

 

구분 서명 예시 코드
정의 타입을 매개변수처럼 사용하는 문법 function identity<T>(value: T): T { return value; }
목적 여러 타입을 안전하게 처리하기 위해 사용 identity(10), identity("hi") 모두 가능
장점 1 재사용성 향상 – 같은 코드로 여러 타입 지원 getFirst<T>(arr: T[]): T
장점 2 타입 안정성 유지 – any보다 안전 컴파일 시 타입 오류 방지
타입 매개변수 일반적으로 T, U, K, V 등 사용 <T>는 Type, <K, V>는 Key, Value
자동 타입 추론 전달된 값에 따라 타입이 자동 결정 echo(123) → T = number
사용 위치 함수 / 인터페이스 / 클래스 / 타입 별칭 interface Box<T> { content: T; }
제한(extends) 특정 타입만 허용할 수도 있음 function print<T extends string>(v: T)

 

 

 

여기까지 제네릭에 대해 알아봤는데요.

 

제네릭 은 초보 때 헷갈리지만, 한 번 이해하면

 

“재사용성”과 “타입 안정성”을 동시에 얻을 수 있는 핵심 기능이니 꼭 알아뒀으면 좋겠어요.

 

'Frontend > TypeScript' 카테고리의 다른 글

Synchronous & Asynchronous & async / await  (0) 2025.11.25
TypeScript Generic(Advanced)  (0) 2025.11.23
TypeScript Interface  (0) 2025.11.21
TypeScript Type  (0) 2025.11.20
TypeScript(TS)  (0) 2025.11.19