Generics
재사용 가능한 클래스로, 함수를 만들기 위해 다양한 타입에서 사용 가능 하도록 하는 것
모든 타입의 객체를 다루면서도 무결성 유지 가능
클래스나 함수 내부에서 사용되는 특정 데이터의 타입을 외부에서 지정 가능(생성자를 이용해서 생성하는 순간 타입 결정)
제네릭이 적용된 대상(클래스, 함수, 인터페이스)은 선언 시점이 아닌 생성 시점에 사용하는 타입을 결정
제네릭 타입은 상속을 통해 특정 하위 타입으로 제한 가능
예시 코드
class Orange {
private name = 'Orange'
constuctor(private brix: number = 0) {}
getName(): string {
return this.name
}
getBrix(): number {
return this.brix
}
}
class Apple {
private name = 'Apple'
constuctor(private brix: number = 0) {}
getName(): string {
return this.name
}
getBrix(): number {
return this.brix
}
}
class Box {
constuctor(private fruit: any = {}) {}
getFruit(): any {
return this.fruit
}
}
// 정상 출력
const box = new Box(new Orange(5))
console.log(box.getFruit().getName())
console.log(box)
// 런타입 에러(해결하려면 매번 새로운 클래스를 생성해야함 -> 이를 위해 제네릭 사용)
const testBox = new Box('Banana')
console.log(testBox.getFruit().getName())
// 제네릭 활용 예시
class Stack<T> {
private data: T[] = [];
constructor() {}
push(item: T): void {
this.data.push(item);
}
pop(): T {
return this.data.pop();
}
}
Type Alias
새로운 타입을 정의하는 방법은 type alias, interface를 정의하는 두 가지 방법이 존재
type alias를 이용하면 객체, 공용체(union), 튜플(tuple), 기본 타입의 별칭을 만들 수 있음
type alias도 제네렉의 사용이 가능하며, 스스로 참조하는 것도 가능
예시 코드
type MyNumber = number
const n: MyNumber = 10
type Container<T> = { value: T }
type User = { name: string, age: number }
const testUser: User = { name: 'Kim', age: 20 }
function printInfo(user: { name: string, age: number }): void {
console.log(`User Infomation - Name: ${user.name}, Age: ${user.age}`)
}
function printInfo(user: User): void {
console.log(`User Infomation - Name: ${user.name}, Age: ${user.age}`)
}