
안녕하세요. 오늘은 타입스크립트 제네릭(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 |