[TypeScript-입문][완료] 14.제네릭(Generic) 추가 설명


TypeScript-입문 카테고리 포스팅은 해당 “제네릭(Generic) 추가 설명” 포스팅으로 끝이다. 이젠 타입스크립트는 예정이 없고 나중에 필요시 다시 복습하게 될 때 포스팅할 기회가 오면 해야겠다.


1. TypeScript에서 제네릭(Generic)

장점:

  1. 유연성과 재사용성: 제네릭을 사용하면 여러 유형에서 동작할 수 있는 유연한 함수, 클래스 또는 인터페이스를 작성할 수 있습니다.
  2. 타입 안정성: 컴파일 시점에서 타입 안정성을 보장하여 런타임 오류를 줄입니다.
  3. 추상화: 제네릭을 사용하여 일반적인 알고리즘을 작성하고, 이를 다양한 유형에 대해 재사용할 수 있습니다.
  4. 코드 가독성 향상: 코드를 보다 간결하고 읽기 쉽게 만들어줍니다.

특징:

  1. 타입 파라미터: 제네릭은 타입 파라미터를 사용하여 함수, 클래스, 인터페이스를 정의합니다. 이를 통해 다양한 유형의 데이터를 처리할 수 있습니다.
  2. 타입 제약(Constraints): 타입 파라미터에 제약을 두어 특정 유형에만 적용되도록 할 수 있습니다.
  3. 타입 추론(Type Inference): 때때로 제네릭은 파라미터로 전달된 유형에 따라 자동으로 타입을 추론할 수 있습니다.
  4. 다형성(Polymorphism): 제네릭을 통해 다형성을 구현하여 여러 유형에서 동일한 코드를 재사용할 수 있습니다.


제네릭의 장점과 특징을 보고 아래 추가 예제코드를 복습해보자.



2. 제네릭(Generic) 추가 예제 코드

기본 Type이 제네릭

//1. T는 기본 Type이 제네릭
function basicSample<T>(data: T) {
  return data;
}

//helloGeneric<string>(123); //타입 에러 발생 : 'number' 형식의 인수는 'string' 형식의 매개 변수에 할당될 수 없습니다.
basicSample<string>("123");


Array Type이 제네릭

//2. T는 Array Type이 제네릭
function arraySample<T>(data: T[]): Array<T> {
  return data;
}

// 문자열 배열 전달
let result1: Array<string> = arraySample(["1", "2", "3"]);
console.log(result1); // 출력: ["1", "2", "3"]

// 문자열과 숫자가 혼합된 배열 전달
let result2: Array<string | number> = arraySample(["1", "2", 3]);
console.log(result2); // 출력: ["1", "2", 3]


Tupple Type이 제네릭

//3. T는 Tupple 0번째 Type이 제네릭
function tupleSample<T, K>(data: [T, K]): T {
  return data[0];
}

// 문자열로 구성된 튜플을 전달
let result3: string = tupleSample(["A", "1234"]);
console.log(result3); // 출력: "A"

// 문자열과 숫자가 혼합된 튜플을 전달
let result4: string = tupleSample(["B", 1234]);
console.log(result4); // 출력: "B"


function 제네릭

//4. Type-Alias 형태로 제네릭 function인 myFun 생성(구현)
type typeGenSample = <T>(data: T) => T;

let myFun1: typeGenSample = <T>(data: T): T => {
  return data;
};

// myFun1 호출 예제
let result5: number = myFun1(10); // 숫자를 전달하여 호출
console.log(result5); // 출력: 10

let result6: string = myFun1("Hello!"); // 문자열을 전달하여 호출
console.log(result6); // 출력: Hello!

//5. Interface 형태로 제네릭 function인 myFun 생성(구현)
interface interfaceGenSample {
  <T>(data: T): T;
}

let myFun2: interfaceGenSample = <T>(data: T): T => {
  return data;
};

// myFun2 함수 호출 예제
let result7: number = myFun2(10); // 숫자를 전달하여 호출
console.log(result7); // 출력: 10

let result8: string = myFun2("Hello!"); // 문자열을 전달하여 호출
console.log(result8); // 출력: Hello!


Class 제네릭

//6. Class 생성자 제네릭 예제
class Lecture<T, K> {
  private name: T;
  private roomNo: K;

  constructor(name: T, roomNo: K) {
    this.name = name;
    this.roomNo = roomNo;
  }
}

// Lecture 클래스의 생성자를 사용하여 객체 생성 예제
let lecture1 = new Lecture<string, number>("Math", 101);
console.log(lecture1); // 출력: Lecture { name: 'Math', roomNo: 101 }

let lecture2 = new Lecture<string, string>("History", "A101");
console.log(lecture2); // 출력: Lecture { name: 'History', roomNo: 'A101' }


제네릭 extends(제한)

//7. Class 생성자 제네릭 extends(제한) 예제
class Students<
  T extends string | number,
  K extends Array<string> | Array<number>
> {
  private roomNo: T;
  private ids: K;

  constructor(roomNo: T, ids: K) {
    this.roomNo = roomNo;
    this.ids = ids;
  }
}

// Students 두번째 인자는 Array type으로 제한을 두고 있다.
let students1 = new Students<number, Array<number>>(101, [1, 2, 3]);
console.log(students1); // 출력: Students { roomNo: 101, ids: [1, 2, 3] }

let students2 = new Students<string, Array<string>>("101", ["1", "2", "3"]);
console.log(students2); // 출력: Students { roomNo: '101', ids: ['1', '2', '3'] }


제네릭을 사용하여 keyof와 타입 조회(type lookup)

// Person 인터페이스를 정의
interface Person {
  name: string;
  age: number;
  email: string;
}

// 제네릭을 사용하여 keyof와 타입 조회를 결합하는 함수를 정의
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// Person 타입 객체를 생성
let person: Person = {
  name: "Alice",
  age: 30,
  email: "alice@example.com"
};

// getProperty 함수를 사용하여 Person 객체의 프로퍼티 값을 가져옴
let personName: string = getProperty(person, "name");
let personAge: number = getProperty(person, "age");
let personEmail: string = getProperty(person, "email");

console.log(personName); // 출력: Alice
console.log(personAge); // 출력: 30
console.log(personEmail); // 출력: alice@example.com




  • https://www.typescriptlang.org/play?#code/Q