제네릭

Tags
generics
부가 설명
재사용성의 극대화
비고
 

제네릭? 언제씀?

한가지 자료형으로 구현했던 클래스를, 다양한 타입으로 가능하도록 만들려면 제네릭을 활용하면 됨.

장점

  • 굉장히 유연함.
  • 타입도 보장 가능
  • 재사용성 극대화

특징

  • 제네릭 타입은 보통 대문자 한글자로 줄여서 사용 ( TYPE → T 로 한글자로 줄여서 사용)
 
제네릭 함수는 type arguments 생략가능.
  • 인수에 의해 타입 매개변수가 결정된다.
제네릭 클래스는 type arguments 반드시 명시.
 

화살표 함수 예시

function foo<T>(x: T): T { return x; } const foo = <T>(x: T) => x;
import { useEffect, useRef } from 'react'; export const usePrevious = <T>(value: T): T | undefined => { const ref = useRef<T>(); useEffect(() => { ref.current = value; }, [value]); return ref.current; };
 

오브젝트 제네릭 예시

type Props<T extends Organizations> = Pick< SimpleAuthParams<T>, 'organization' | 'RRN' | '간편인증방법' | 'userName' | 'phoneNumber' >;

예시1

export const 간편인증 = async <T extends Organizations>({ accessToken, 서비스명, organization, RRN, 간편인증방법, userName, phoneNumber, onFinish, additionalParams, }: { accessToken: string; organization: T; 서비스명: 기관별_서비스_타입[T]; RRN: string; 간편인증방법: 간편인증종류; userName: string; phoneNumber: string; onFinish: ResponseHandler; additionalParams?: Object; }): Promise<void> => {
만약에 프롭이 별도 타입으로 나와야 한다면 아래와 같이 변경할 수도 있다.
export interface SimpleAuthParams<T extends Organizations> { accessToken: string; organization: T; 서비스명: 기관별_서비스_타입[T]; RRN: string; 간편인증방법: 간편인증종류; userName: string; phoneNumber: string; onFinish: ResponseHandler; additionalParams?: Object; } export const 간편인증 = async <T extends Organizations>({ accessToken, 서비스명, organization, RRN, 간편인증방법, userName, phoneNumber, onFinish, additionalParams, }: SimpleAuthParams<T>): Promise<void> => { ... }

예시2

// [ToDo] 타입 좀 깔끔하게 만들 수 없을까? for문 돌리는 느낌인데.. type 서비스Type = { 건강보험공단: { 건강보험공단_심뇌혈관_질환예측: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_심뇌혈관_질환예측'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_심뇌혈관_질환예측'; }; 건강보험공단_당뇨병예측: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_당뇨병예측'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_당뇨병예측'; }; 건강보험공단_심장질환예측: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_심장질환예측'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_심장질환예측'; }; 건강보험공단_뇌졸중_예측: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_뇌졸중_예측'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_뇌졸중_예측'; }; 건강보험공단_골다공증성골절예측: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_골다공증성골절예측'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_골다공증성골절예측'; }; 건강보험공단_건강나이알아보기: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_건강나이알아보기'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_건강나이알아보기'; }; 건강보험공단_건강검진결과: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_건강검진결과'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_건강검진결과'; }; 건강보험공단_진료받은_내용: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_진료받은_내용'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_진료받은_내용'; }; 건강보험공단_진료_및_투약정보: { apiName: string; endpoint: string; etcParams: Omit< 서비스Params['건강보험공단']['건강보험공단_진료_및_투약정보'], keyof SimpleAuthBaseParams >; 서비스명: '건강보험공단_진료_및_투약정보'; }; }; 보건복지부: { 내가먹는약_한눈에: { apiName: string; endpoint: string; etcParams: Object; 서비스명: '내가먹는약_한눈에'; }; }; };
위의 타입을 제네릭을 활용하면 아래와 같이 깔끔하게 정리할 수 있다.
interface 서비스Type<O extends Organizations, S extends 기관별_서비스_타입[O]> { T: { S: { apiName: string; endpoint: string; etcParams: Omit<서비스Params[O][S], keyof SimpleAuthBaseParams>; 서비스명: S; }; }; }