typeScript Generic / Utility 본문
반응형
Generic
제네릭을 사용하면 다양한 방식으로 자신만의 타입을 사용할 수 있다.
제네릭은 Type 을 함수의 파라미터처럼 사용할 수 있는 것을 의미하는데,
기본 타입과 Generic 을 적용한 타입을 비교해보고자 한다.
기본 타입
문자 / 숫자 / 불리언 || any || unknown
// 1. 문자/숫자/불린 기본 타입
const getPrimitive = (arg1: string, arg2: number, arg3: boolean): [boolean, number, string] => {
return [arg3, arg2, arg1]; // type 으로 정해놓은 값만 반환이 가능하다.
};
const result = getPrimitive("철수", 123, true);
//
//
// 2. any 타입 (그냥 자바스크립트와 같음)
const getAny = (arg1: any, arg2: any, arg3: any): [any, any, any] => {
console.log(arg1 + 100); // any 는 자바스크립트와 같이 어떤 타입이든 적용이 가능하다.
return [arg3, arg2, arg1];
};
const result = getAny("철수", 123, true);
// 하지만, 타입스크립트는 그말마따나 목적이 '타입'을 정해주는 것에 있기 때문에 사용하지 않는 편이 좋다.
//
//
// 3. unknown 타입 // 타입을 모를 때는 unknown 을 통해 원하는 결과에 해당 타입을 유추해 명시해준다.
const getUknown = (arg1: unknown, arg2: unknown, arg3: unknown): [unknown, unknown, unknown] => {
if (typeof arg1 === "number") console.log(arg1 + 100);
return [arg3, arg2, arg1];
};
const result = getUknown("철수", 123, true);
정석으로 보이는 typescript 사용 방법이라고 볼 수 있으나, 범용성이 떨어지는 편이다.
특히 any 의 경우 타입을 제한할 수 없을 뿐더러, 어떤 타입의 데이터가 리턴되는지 알 수 없다는 문제점도 있다.
이런 문제점 때문에 등장한 것이 Generic.
generic 타입은 어떤 타입인지는 모르지만 다양한 타입에서 작동하는 코드를 작성할 수 있다.
// generic 타입 < >
function getGeneric<MyType1, MyType2, MyType3>(arg1: MyType1, arg2: MyType2, arg3: MyType3): [MyType3, MyType2, MyType1] {
return [arg3, arg2, arg1];
}
const result = getGeneric<string, number, boolean>("철수", 123, true);
//
//
// generic 타입 2 // T의 경우 generic 선언 시 자주 타입변수로써 범용적으로 사용한다.
function getGeneric2<T1, T2, T3>(arg1: T1, arg2: T2, arg3: T3): [T3, T2, T1] {
return [arg3, arg2, arg1];
}
const result = getGeneric2<string, number, boolean>("철수", 123, true);
//
//
// generic 타입 3 꼭 T가 아니라, 어떤 문자를 사용하든 상관 없다.
function getGeneric3<T, U, V>(arg1: T, arg2: U, arg3: V): [V, U, T] {
return [arg3, arg2, arg1];
}
const result = getGeneric3<string, number, boolean>("철수", 123, true);
// generic 타입 화살표 함수
const getGeneric4 <T, U, V>(arg1: T, arg2: U, arg3: V): [V, U, T] => {
return [arg3, arg2, arg1];
}
const result = getGeneric4("철수", 123, true);
중요한 건, 꺽쇠를 사용하여 제네릭 타입임을 명시해주어야 타입스크립트가 들어온 데이터의 타입을 추론할 수 있게 된다.
화살표 함수로도 활용할 수 있다는 것을 기억해두자.
Utility
유틸리티란 공통적인 타입을 변환하는데에 용이하게 사용하는 데에 도움을 준다.
대표적인 utility 를 소개한다.
interface IProfile {
name: string;
age: number;
school: string;
hobby?: string;
}
// 1. partial 타입 (필수 요소 해제)
type aaa = Partial<IProfile>;
// IProfile의 모든 요소들이 필수적으로 요구하는 값이 아니게 된다.
// 'hobby?' 과 같은 특성을 갖게 된다는 의미.
// 2. required 타입 (모든 요소 필수)
type bbb = Required<IProfile>;
// IProfile 의 모든 요소가 partial과 반대로 모든 값이 필수 요구하는 값이 된다.
// 3. pick 타입 (필요한 요소 선택 / 이름 나이)
type ccc = Pick<IProfile, "name" | "age">;
// 원하는 요소만 선택할 수 있게 된다.
// 4. omit 타입 (불필요한 요소 제외 / 스쿨 제외)
type ddd = Omit<IProfile, "school">;
// pick 과 반대.
// 5. Record 타입 // 다른 타입에 매핑시키는데 사용한다.
type eee = "철수" | "영희" | "훈이"; // union 타입 / key : value 로 사용 가능
let child: eee = "영희"; // union 타입으로 가져오기 때문에 '철수, 영희, 훈이'만 가능
type fff = Record<eee, IProfile>; // Record 타입으로 eee에 IProfile 타입 적용
// 6. 객체의 Key들로 union 타입 만들기
type ggg = keyof IProfile; // 'name' | 'age' | 'school' | 'hobby'
let myprofile: ggg = "hobby";
// 7. type vs interface 의 차이 => interface는 선언병합 가능
interface IProfile {
candy: number; // 선언 병합으로 추가됨
}
// 8. 배운 내용 응용
let profile: Partial<IProfile> = {
candy: 10
};
반응형
'개발 > nest.js' 카테고리의 다른 글
집계 & 정렬 & 서브 쿼리 (0) | 2023.02.04 |
---|---|
nestJS - MySQL과의 연동 (0) | 2023.02.01 |
eslint & prettier (0) | 2023.01.30 |
TypeScript - decorator / public & private & protected & readonly (0) | 2023.01.28 |
느슨한결합(loose-coupling)& 의존성주입(DI) (0) | 2023.01.27 |
Comments