ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TypeScript] 타입스크립트 제네릭
    Web/TypeScript 2024. 11. 20. 17:44

     


    - 제네릭이란?

     

    제네릭은 타입을 미리 지정하지 않고 사용하는 시점에 타입을 정의해서 쓸 수 있는 문법을 말한다.

    // 제네릭 함수
    function identity<T>(value: T): T {
        return value;
    }
    
    console.log(identity(42));       // 42
    console.log(identity("hello"));  // hello

     

    위의 코드에서는 <T>를 통해서 제네릭을 지정했다.

     

    그로 인해 number 타입, string 타입이 성공적으로 출력되는 것을 확인할 수 있다.

     

     

    아래의 코드는 유니온 타입을 제네릭으로 바꾼 예시이다.

    const firstElement = (elements: number[] | string[]) => elements[0];
    
    firstElement([1, 2, 3]); // 1
    firstElement(["a", "b", "c"]); // 'a'
    
    // 위의 코드를 제네릭으로 바꾸기
    const firstElement = <T>(elements: T[]): T => {
        return elements[0];
    };
    
    firstElement([1, 2, 3]); // 1
    firstElement(["a", "b", "c"]); // 'a'

     

     

    - 인터페이스에서의 제네릭

    또한 제네릭인터페이스에도 사용이 가능하다.

     

    아래는 제네릭을 사용하여 인터페이스를 정의한 예시이다.

    interface Box<T> {
        value: T;
        getValue(): T;
    }
    
    const numberBox: Box<number> = {
        value: 123,
        getValue() {
            return this.value;
        }
    };
    
    const stringBox: Box<string> = {
        value: "hello",
        getValue() {
            return this.value;
        }
    };
    
    console.log(numberBox.getValue()); // 123
    console.log(stringBox.getValue()); // "hello"

     

     

    - 타입 별칭(Type alias) 에서의 제네릭

    제네릭타입 별칭(Type alias)으로도 사용이 가능하다.

    type Result<T> = {
        success: boolean;
        data: T;
    };
    
    const result1: Result<number> = {
        success: true,
        data: 42
    };
    
    const result2: Result<string> = {
        success: false,
        data: "error"
    };
    
    console.log(result1); // { success: true, data: 42 }
    console.log(result2); // { success: false, data: "error" }

     

     

    - 타입 제약

    extends 키워드를 사용해 타입 제약이 가능하다.

     

    여기서 타입 제약이란, 제네릭의 타입을 제한하고 싶을 때 사용한다.

     

    아래의 코드는 T가 length라는 속성을 가지고 있으며, 그 타입이 number여야 한다는 제한을 걸었다.

    function logLength<T extends { length: number }>(item: T): void {
        console.log(item.length);
    }
    
    logLength("Hello"); // 5
    logLength([1, 2, 3]); // 3
    // logLength(123); // 오류: number는 length 프로퍼티가 없음

     

     

    아래의 코드는 T가 toUpperCase() 메소드를 가진 타입이어야 한다는 제한을 걸었다.

    interface IResponse<T> {
        status: number;
        data: T;
    }
    
    function toUppercase<T extends { toUpperCase: () => T }>(value: T): T {
        return value.toUpperCase();
    }
    
    toUppercase<string>("abc");
    toUppercase<number>(123); // error, toUppercase()가 없음

     


    참고 강의: https://www.sucoding.kr/
Designed by Tistory.