[ts] 제네릭

2023. 12. 22. 16:09· 프론트엔드/Typescript

https://www.typescriptlang.org/ko/docs/handbook/2/generics.html

 

단일 타입이 아닌, 다양한 타입을 동적으로 정의할 수 있음.

코드의 재사용성과 유연성 증가, 코드를 추상화된 형태로 작성할 수 있게 됨

1. 제네릭 함수

function identity<T>(arg: T): T {
  return arg;
}

let result1: number = identity<number>(42); // result1의 타입은 number  
let result1: number = identity(42); // 타입 추론 사용

let result2: string = identity<string>("hello");  // result2의 타입은 string
let result2: string = identity("hello");  // 타입 추론 사용
  • <T> 제네릭 타입 매개변수 : 꺽쇠를 변수명,함수명 앞에 쓰면 "타입 단언"이 된다.
  • (arg : T) : 함수의 매개변수는 T타입이여서, 어떤 타입의 인수라도 받을 수 있음
  • :T : 함수의 리턴값에 대한 타입 정의
  •  
function loggingIdentity<T>(arg: T[]): T[] {
  return arg;
}

let result1: number[] = loggingIdentity([1, 2, 3]); 
let result2: string[] = loggingIdentity(["a", "b", "c"]);

// 타입 추론 사용됨. 때문에 loggingIdentity<number[]>([1, 2, 3]); <- 불필요
  • <T> 제네릭 타입 매개변수 : <T>을 통해 어떤 타입의 배열을 받을지 동적으로 결정할 수 있음
  • (arg: T[]) :함수의 매개변수는 T타입이여서,배열의 원소들이 어떤 타입이라도 받을 수 있음
  • T[] :함수의 리턴값에 대한 타입 정의, 받은 타입과 동일한 타입의 배열을 반환함.

 

2. 함수를 값으로 쓰기

- 변수에 함수 할당할 때 유용 

- 함수 자체를 매개변수로 전달할 때 유용

 

myIdentity라는 변수에 identity 함수를 할당하는 코드
: myIdentity 변수는 identity 함수와 동일한 함수 타입을 갖게 됨.

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: <T>(arg: T) => T = identity;  // 일반 js라면, let myIdentity = identity함수

let result1: number = myIdentity(42);        // result1의 타입은 number
let result2: string = myIdentity("hello");   // result2의 타입은 string

 

3. 제네릭 인터페이스

interface Pair<K, V> {
    key: K;
    value: V;
}

// 문자열과 숫자를 담은 Pair 인스턴스
let keyValue: Pair<string, number> = { key: "age", value: 25 };
 
 // 문자열과 불린형을 담은 Pair 인스턴스
let keyValue: Pair<string, boolean> = { key: "admin", value: true };
  • Pair는 제네릭 인터페이스 : K,V을 타입 매개변수로 받아 동적으로 타입이 결정됨
  •  Pair<string , number> : Paire<K,V>에 타입 매개변수가 할당됨

 4. html요소의 기본 속성을 확장하기 위한 제네릭 

// 부모 컴포넌트 App.tsx
<AssetImage image={item.image} className="prods-img" />
 
// 자식 컴포넌트 AssetImage.tsx
import { HTMLProps } from "react";

interface AssetImageProps extends HTMLProps<HTMLImageElement> {
  image?: string;
}

function AssetImage({ image, ...props }: AssetImageProps) {
  return <img src={imageUrl} {...props} />;
}

export default AssetImage;

 

  • AssetImageProps 인터페이스가 HTMLImageElement 요소에 대한 모든 속성을 상속한 것임
    이미지 엘리먼트에 사용되는 모든 표준 HTML 속성을 AssetImageProps에서도 사용할 수 있게 됨

Promise<T>
: 제네릭을 어디에 붙여야 하는지 어떻게 앎? prmise에 제네릭을 붙여야 한다는걸 어떻게 파악?

export interface GetManyResponse<T> {
  docs: T[];
  include?: any;
  limit: number;
  totalDocs: number;
}

export const useGetManyProduct = (prodQuery: ProductQueryParams) => {
  return useQuery({
    placeholderData: keepPreviousData, // https://tanstack.com/query/v5/docs/react/guides/paginated-queries <- layout shifting이 일어나지 않아, 레이아웃이 깨지지 않는다.
    // [제네릭] 2
    queryFn: (): Promise<GetManyResponse<Product>> => {
      return axiosInstance({
        method: "get",
        params: prodQuery,
        url: `/product`
      }).then((res) => res.data);
    },
    queryKey: ProductQuery.getMany(prodQuery) // ['all','getMany',{sort:price, title[match] :'Women'}]
    // refetchOnWindowFocus: isRefecth, // 탭을 나갔다가 다시 탭 눌렀을때, stale됐으면 자동으로 refetch되는 기능
  });
};

 


https://feel5ny.github.io/2018/12/09/Typescript_14/

'프론트엔드 > Typescript' 카테고리의 다른 글

타입스크립트의 필요성에 대해  (1) 2025.01.05
'프론트엔드/Typescript' 카테고리의 다른 글
  • 타입스크립트의 필요성에 대해
journey-dev
journey-dev
journey-dev
journey-dev
journey-dev
전체
오늘
어제
  • 분류 전체보기 (65)
    • 프론트엔드 (44)
      • JS (8)
      • React (8)
      • vue (9)
      • Typescript (2)
    • CS (4)
      • 자료구조&알고리즘 (2)
      • 네트워크 (2)
    • 개발서적 (1)
      • 코어 자바스크립트 (0)
      • 프론트엔드 성능 최적화 가이드 (1)
    • DB (11)
      • SQL (11)
    • GIT (0)
    • GIS (3)
    • 개발일기 (2)
    • ing (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 일단 시작해라. 나중에 완벽해지면 된다.

인기 글

태그

  • 리액트 복기하기!

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
journey-dev
[ts] 제네릭
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.