
프론트엔드
TypeScript GenericsTypeScript 제네릭
TypeScript 제네릭(Generics)은 타입을 매개변수로 받아 재사용 가능한 타입 안전 코드를 작성하는 기능이다. any 대신 타입 안전성을 유지하면서도 다양한 타입에 동작하는 함수, 클래스, 인터페이스를 만들 수 있다.
기본 문법
typescript
// 제네릭 함수
function identity<T>(arg: T): T {
return arg;
}
const str = identity<string>('hello'); // 명시적
const num = identity(42); // 타입 추론
// 여러 타입 매개변수
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
const result = pair('hello', 42); // [string, number]제약 조건 (Constraints)
typescript
// extends로 타입 제약
interface HasLength {
length: number;
}
function getLength<T extends HasLength>(item: T): number {
return item.length;
}
getLength('hello'); // OK
getLength([1, 2, 3]); // OK
getLength(42); // Error: number에 length 없음
// keyof 제약
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Alice', age: 30 };
const name = getProperty(user, 'name'); // string
const age = getProperty(user, 'age'); // number
// getProperty(user, 'email'); // Error제네릭 인터페이스와 클래스
typescript
// 제네릭 인터페이스
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
save(entity: T): Promise<T>;
delete(id: string): Promise<void>;
}
// 제네릭 클래스
class Stack<T> {
private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }
isEmpty(): boolean { return this.items.length === 0; }
}
const numStack = new Stack<number>();
numStack.push(1);
numStack.push(2);
console.log(numStack.pop()); // 2유틸리티 타입 구현
typescript
// TypeScript 내장 유틸리티 타입 구현 원리
// Partial<T>: 모든 프로퍼티를 선택적으로
type MyPartial<T> = {
[P in keyof T]?: T[P];
};
// Required<T>: 모든 프로퍼티를 필수로
type MyRequired<T> = {
[P in keyof T]-?: T[P];
};
// Pick<T, K>: 특정 프로퍼티만 선택
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
// Readonly<T>
type MyReadonly<T> = {
readonly [P in keyof T]: T[P];
};
// ReturnType<T>
type MyReturnType<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : never;관련 개념
- •TypeScript 데코레이터
- •타입스크립트