TS스크립트-Generic

박경찬·2022년 9월 16일
0

타입스크립트 에서 Generic을 알아보고 이를 이용해서 !

HOC - HOF - COOKIE - LocalStroage - SessionStroage

까지 공부해보고자 한다!

이번 포스팅은 타입스크립트에서 어마무시한 타입인 Generic을 한번 살펴보자!

any unknown 두 가지 부터 살표보자😎

const get = (args: any) => {
  return args + 2;
};

const getResult = get("철수");

위 함수는 args를 인자값으로 받을때 타입은 모든 타입을 받는다는 의미다. 즉 어떤 타입이 들어 오는지 모른다
그리고 변수를 확인해보면 any 타입으로 확인된다.

여기서 getResult 하게되면 철수는 지워지게 되고 args+2 철수 자리로 가게된다. 하지만 타입을 모르기 때문에 getResultany로 확인된다

위 내용은 자바스크립트 와 별차이가 없다🫢 그럼 여기서 한단계 더 발전한 타입이 있다.

unknown 이라고 한다!!

unknown 도 any 랑 비슷하면서도 다르다 둘의 차이점은
any는 모든타입이 들어갈수 있지만 unknown은 "

const uknown = (args: unknown) => {
  return args + 2;
};
const getResult2 = uknown("철수");

return 문에서 "개체가 알 수 없는 형식이다" 라고 알려준다
unknown은 현재는 모를수 있으나 상황에 따라서 코딩을 통해 숫자인지 문자인지 구체적으로 알려줘야 한다.

const uknown = (args: unknown) => {
  if (typeof args === "number") {
    return args + 2;
  } else {
    return "숫자를 넣어주세요";
  }
};

위 내용을 보면 타입스크립트를 사용할때 any 타입은 지양한다
주로 unknown 을 사용해서 구체적으로 타입을 알려줘야한다!
그리고 결과에 대한 예측도 할수 있다. 가장 중요한건 개발자가 안전한게 코딩을 할수 있다! 코드량이 조금 늘지만 전체적으로 안정감 있는 프로그램을 구현할수 있다.

이렇게 말했지만 실제 프로젝트에서는.. any를 많ㅇ..🫢

이걸 바탕으로 Generic을 살펴 보자!☝🏼

const getString1 = (args: string): string => {
  return args;
};

const getString = getString1("철수");

getString1 자리에 문자타입 args 가 들어가게 된다.
우리는 여기서 조금 달라진 코드를 볼수 있다. 인수 옆에 타입을 하나더 적어줬는데 저기서 말하는 타입은 return 되는 타입을 정의해준것이다.

return 되는 타입을 number로 바꿔주면 어떻게 될까?
받아 오는 인자값이 문자값이고 return 하고 있는 args도 문자값이기 때문에 return 문에서 오류가 나타난다.

"string" 형식은 "number" 형식에 할당할수 없다

any 타입으로 실습 해봤던 코드를 들고와서 Generic을 살펴보자

const get1 = (args: any) => {
  return args + 2;
};

const getResult1 = get1("철수");
const getResult2 = get1(8);
const getResult3 = get1(true);

코드를 보면 아시다시피 any 타입은 어떤타입의 데이터든지 들어올수 있다 하지만 any의 문제점은 값을 예상할수 없고 코드자체가 안전하지 못한다.

이문제를 개선하기 위해 사용하는게 Generic이다.

function getGeneric(arg:any): any {
  return arg;
}

const string1: string = "오렌지";
const string2: number = 10;
const string3: boolean = true;

const getGeneric1 = getGeneric(string1);
const getGeneric2 = getGeneric(string2);
const getGeneric3 = getGeneric(string3);

변수 3개를 추가 해서 값 타입에 맞게 값을 할당해줬다. 아직까지는 인자값의 타입이 any 타입이기 때문에 아직 어떤 값이 들어오고 return될지 모른다.

function getGeneric<MyType>(arg: MyType): MyType {
  return arg;
}

const string1: string = "오렌지";
const string2: number = 10;
const string3: boolean = true;

const getGeneric1 = getGeneric(string1);
const getGeneric2 = getGeneric(string2);
const getGeneric3 = getGeneric(string3);

any에서 MyType은 뭔가? any랑 같지만 다르다 어떤 타입의 데이터든지 들어 올수 있지만 들어온 타입을 그대로 사용한다.

MyType에 문자타입이 들어오면 return되는 타입도 인자가 받아오는 데이터 타입을 따라가기 때문에 결과값도 예측할수 있다.



정리하자면 Generic은 들어오는 데이터 타입은 모르지만 할당된 데이터 타입을 사용하고 return 해주는 역할이 Generic이다.

그렇다면 배열은 어떻게 할까?

function getGenerics2<MyType>(
  arg1: MyType,
  arg2: MyType,
  arg3: MyType
): [MyType, MyType, MyType] {
  return [arg1, arg2, arg3];
}
const getGenerics = getGenerics2("파인애플", 10, true);

이렇게 되면 첫 인자값 이 string 이기 때문에 return 되는 데이터 타입도 string이 된다. 그런데 우리는 두번째 인값이 number , 3번째 인자값이 boolean 이다.

이럴 경우에는 type을 개별로 정의 해줘야한다.

function getGenerics2<MyType1, MyType2, MyType3>(
  arg1: MyType1,
  arg2: MyType2,
  arg3: MyType3
): [MyType1, MyType2, MyType3] {
  return [arg1, arg2, arg3];
}
const getGenerics = getGenerics2("파인애플", 10, true);

어떤 데이터 타입이 인자값에 할당될지 모르지만 할당된 타입을 가지고 return을 해주기 때문에 위 코드 내용처럼 각각 타입을 정해 <> 꺽새로 묶어줘야한다.

똑같이 결과값도 예상할수 있따.

하지만 위 코드내용이 좀 많타.. 줄여보자
위에서 사용한 MyType은 필자가 임의로 이름을 만들어준거기 때문에
짧게 만들수도 있다.

function getGenerics2<T, G, L>(arg1: T, arg2: G, arg3: L): [T, G, L] {
  return [arg1, arg2, arg3];
}
const getGenerics = getGenerics2("파인애플", 10, true);

Generic 타입에도 명시를 해줄수가 있다.

function getGenerics2<T, G, L>(arg1: T, arg2: G, arg3: L): [T, G, L] {
  return [arg1, arg2, arg3];
}
const getGenerics = getGenerics2<string, number, boolean>("파인애플", 10, true);

0개의 댓글