제네릭을 쓰는이유
내가만든 함수의 타입을 지정할때 다른사람이 사용하거나 내가 다시 사용할 경우
어떤 타입을 써야하는지 알수없음
그럼 any를 쓰면되지만 any 를 쓰면 아무 타입이나 전부 허용하고 무슨타입인지 구분이 되지않음
이러면 타입스크립트를 쓰는 의미가 없어짐
그래서 아무 타입이나 전부 사용 할 수 있지만 타입의 구분이 가능한 Generic을 사
Generic 타입
// 문자 / 숫자 /불린 기본타입
// 1. 문자/숫자/불린 기본타입
const getPrimitive = (arg1: string, arg2: number, arg3: boolean): [boolean, number, string] => {
return [arg3, arg2, arg1];
};
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 타입
const getUnknown = (arg1: unknown, arg2: unknown, arg3: unknown): [unknown, unknown, unknown] => {
if (typeof arg1 === "number") console.log(arg1 + 100); // unknown 은 if 문으로 별도로 지정해줘야함
return [arg3, arg2, arg1];
};
const result = getUnknown("철수", 123, true);
//
//
//4. generic 타입
function getGeneric<Mytype1, Mytype2, Mytype3>(arg1: Mytype1, arg2: Mytype2, arg3: Mytype3): [Mytype3, Mytype2, Mytype1] {
return [arg3, arg2, arg1]; // any 와 다르게 타입이 예측이 됨
}
getGeneric 뒤에 타입을 명시해주면 명시한 타입 이외는 오류가 남
const result = getGeneric<string, number, boolean>("철수", 123, true);
//
//
//4. generic 타입 -2
function getGeneric2<t1, t2, t3>(arg1: t1, arg2: t2, arg3: t3): [t3, t2, t1] {
return [arg3, arg2, arg1];
}
// getGeneric 뒤에 타입을 명시해주면 명시한 타입 이외는 오류가 남
const result = getGeneric2<string, number, boolean>("철수", 123, true);
//
//
//4. generic 타입 -3
function forRoot<t>(arg1: t): [t] {
return [arg1];
}
// getGeneric 뒤에 타입을 명시해주면 명시한 타입 이외는 오류가 남
const result = forRoot<ApolloDriverConfig>({...});
//
//
//4. generic 타입 -4
const getGeneric4 = <t, u, v>(arg1: t, arg2: u, arg3: v): [v, u, t] => {
return [arg3, arg2, arg1];
};
// getGeneric 뒤에 타입을 명시해주면 명시한 타입 이외는 오류가 남
const result = getGeneric4<string, number, boolean>("철수", 123, true);
Utility 타입
//Iprofile 이라는 프로필을 만들었는데
// 어떤 경우에서는 hobby 가 반드시 필요한 경우가 생김
// 이럴경우에 이런식으로 복사해서 만들어주면 되지만
// 코드가 너무 비효율적일 뿐아니라 name 같은 항목이 수정되면 코드 전체를 다 바꿔야함
// interface Iprofile2 {
// name: string;
// age: number;
// school: string;
// hobby: string;
// }
interface Iprofile {
name: string;
age: number;
school: string;
hobby?: string;
}
//1. Partial 타입
// aaa 타입은 전부 ? 가 붙은 타입이 됨 (전부 안적어도되는 타입으로 )
type aaa = Partial<Iprofile>;
//2. Required 타입
// bbb 타입은 전부 필수로 작성해아하는 타입이 됨
type bbb = Required<Iprofile>;
//3. Pick 타입
// ccc 타입은 내가 고른 타입만 필수로 작성 해야 되는 타입
type ccc = Pick<Iprofile, "name" | "age">;
//4. Omit 타입
/// ddd 타입은 제외하는 타입빼고 전부 필수
type ddd = Omit<Iprofile, "school">;
//5. Record 타입
type eee = "철수" | "영희" | "훈이"; // Union 타입
//let child1: eee = "맹구"; //여기는 유니온에 지정한 철수 영희 훈이 말고는 안됨 맹구 x
let child2: string = "사과"; // 유니온 뿐만 아니라 문자열이면 전부 다됨
type fff = Record<eee, Iprofile>; // Record 타입
// fff = {
// 철수 : Iprofile
// 영희 : Iprofile
// 훈이 : Iprofile
// }
//6 객체의 key 들로 Union 타입 만들기
type ggg = keyof Iprofile; // ggg = "name" | "age" | "school" | " hobby"
let myprofile: ggg = "hobby"; //
//7. type vs interface 의 차이
//interface 는 선언 병합 가능 (같은 이름의 타입을 만들면 병합이 됨)
// type 은 안됨
interface Iprofile {
candy: number; // 선언병합으로 추가됨
}
// 캔디만 넣었을때 에러가 나는것은
// 병합된 name age school 이 없기때문 (hobby 는 필수가아님)
// 해결법1은 안에 name age school 를넣어주던가
//해결법2는 name age school 가 필수가 아니게 만들어주면됨 (Partial 붙여주면 됨)
// let profile: Iprofile = {
// candy: 10,
// };
// 해결법2
let profile: Partial<Iprofile> = {
candy: 10,
};'NEST.js' 카테고리의 다른 글
| NEST validation, 수정api (0) | 2023.10.01 |
|---|---|
| NEST API 만들기 (0) | 2023.09.30 |
| NEST GraphQL (0) | 2023.09.29 |
| NEST API구조 (0) | 2023.09.29 |
| NEST eslint / prittier (0) | 2023.09.28 |