728x90
제네릭이란?
종합 병원은 영어로 제네릭 호스피탈이라고 말한다. 그래서 제네릭 함수라함은 모든 타입에 두루두루 사용할 수 있는 범용적인 함수를 의미한다. 함수 계의 종합 병원이랄까...이 개념이 제네릭을 이해하는데 제일 도움이 되는 것 같다.
제네릭을 사용한 경우, 해당 함수를 호출할 때마다 타입이 결정된다.
기본 예시
function func<T>(value: T): T {
return value;
}
let num = func(10);
// number 타입
매개변수 타입이 다른 경우
function swap<T, U>(a: T, b: U) {
return [b, a];
}
const [a, b] = swap("1", 2);
데이터 배열을 받아오는 경우
function returnFirstValue<T>(data: T[]) {
return data[0];
}
let num = returnFirstValue([0, 1, 2]);
// number
let str = returnFirstValue([1, "hello", "mynameis"]);
// number | string
반환 값의 타입이 다른 경우
unction returnFirstValue<T>(data: [T, ...unknown[]]) {
return data[0];
}
let str = returnFirstValue([1, "hello", "mynameis"]);
// number
data.length에 unknwon 타입이라고 뜰 때
interface extend를 생각해보면 된다.
function getLength<T extends { length: number }>(data: T) {
return data.length;
}
getLength("123"); // ✅
getLength([1, 2, 3]); // ✅
getLength({ length: 1 }); // ✅
getLength(5) // ❌ -> number는 length 프로퍼티 없음
getLength(undefined); // ❌
getLength(null); // ❌
map 메서드 타입 정의
function map(arr: unknown[], callback: (item: unknown) => unknown): unknown[] {}
// 제네릭 적용한 예시
const arr = [1, 2, 3];
// <T>: 제네릭 선언
// arr: T[] : 한 타입으로 배열이 들어온다 (ex) string)
// item: T : 그 arr을 맵을 돌렸을 때 나오는 각각 아이템들이 string이다.
// => T: 그리고 반환 값도 같은 타입이다.
// : T[] : 맵을 돌려서 다시 받은 배열은 string으로 이루어진 배열이다.
function map<T>(arr: T[], callback: (item: T) => T): T[] {
(...)
}
map(arr, (it) => it * 2);
// number[] 타입의 배열을 반환
// 결과 : [2, 4, 6]
제네릭 인터페이스
interface Student {
type: "student";
school: string;
}
interface Developer {
type: "developer";
skill: string;
}
interface User {
name: string;
profile: Student | Developer;
}
function goToSchool(user: User<Student>) {
if (user.profile.type !== "student") {
console.log("잘 못 오셨습니다");
return;
}
const school = user.profile.school;
console.log(`${school}로 등교 완료`);
}
const developerUser: User = {
name: "이정환",
profile: {
type: "developer",
skill: "typescript",
},
};
const studentUser: User = {
name: "홍길동",
profile: {
type: "student",
school: "가톨릭대학교",
},
};
----------------------------------------
(...)
interface User<T> {
name: string;
profile: T;
}
function goToSchool(user: User<Student>) {
const school = user.profile.school;
console.log(`${school}로 등교 완료`);
}
const developerUser: User<Developer> = {
name: "이정환",
profile: {
type: "developer",
skill: "TypeScript",
},
};
const studentUser: User<Student> = {
name: "홍길동",
profile: {
type: "student",
school: "가톨릭대학교",
},
};
promise (자바스크립트 비동기 함수용 내장 객체)
interface Post {
id: number;
title: string;
content: string;
}
function fetchPost(): Promise<Post> {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
id: 1,
title: "게시글 제목",
content: "게시글 본문",
});
}, 3000);
});
}
정말 쉽게 설명해주시는 것 같다. 제너릭은 항상 까다롭다고 생각했는데,,, 되게 쉽게 느껴진다.
[참고]
제네릭 소개 - 제네릭
한 입 크기로 잘라먹는 타입스크립트
ts.winterlood.com
728x90
반응형
'TypeScript' 카테고리의 다른 글
유틸리티 타입 Pick<T, K> 프젝에 적용하기 | TypeScript (0) | 2024.03.19 |
---|---|
TypeScript, Next.js, React.js 이미지 미리보기 | Image Preview (0) | 2024.03.18 |
TypeError: Cannot read properties of undefined (reading 'length') 의 원인과 해결 방안 (0) | 2024.03.09 |
서로소 유니온 타입 | 한 입 크기로 잘라먹는 타입스크립트 (0) | 2024.03.03 |