TypeScriptTypeScript 기초강의 8개 중 4번째난이도 기초

함수와 제네릭 — 재사용 가능한 타입 안전 코드

발행 읽는 시간 약 1 분

  • TypeScript
  • 함수
  • 제네릭
  • generic
  • 오버로드

강의 소개

TypeScript에서 함수 타입을 정의하고, 제네릭으로 어떤 타입에도 동작하는 범용 함수와 클래스를 만드는 방법을 배웁니다.

함수 타입 정의#

TypeScript
// 매개변수와 반환 타입
function add(a: number, b: number): number {
    return a + b;
}

// 화살표 함수
const multiply = (a: number, b: number): number => a * b;

// 선택적 매개변수
function greet(name: string, greeting?: string): string {
    return `${greeting ?? "안녕하세요"}, ${name}님!`;
}

// 기본값
function createUser(name: string, role: string = "user"): object {
    return { name, role };
}

함수 타입 별칭#

TypeScript
// 타입으로 함수 시그니처 정의
type MathOperation = (a: number, b: number) => number;
type Formatter = (value: string) => string;

const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;

// 콜백 타입
type EventHandler = (event: MouseEvent) => void;
type AsyncTask<T> = () => Promise<T>;

나머지 매개변수#

TypeScript
function sum(...numbers: number[]): number {
    return numbers.reduce((acc, n) => acc + n, 0);
}

sum(1, 2, 3);       // 6
sum(1, 2, 3, 4, 5); // 15

제네릭 (Generics)#

타입을 매개변수처럼 다루어 재사용 가능한 코드를 만듭니다.

TypeScript
// 제네릭 없이 — 타입별로 함수 중복
function getFirstString(arr: string[]): string {
    return arr[0];
}
function getFirstNumber(arr: number[]): number {
    return arr[0];
}

// 제네릭으로 — 하나의 함수로 모든 타입 처리
function getFirst<T>(arr: T[]): T {
    return arr[0];
}

getFirst<string>(["a", "b", "c"]);  // "a"
getFirst<number>([1, 2, 3]);        // 1
getFirst(["a", "b"]);               // 타입 추론: string

제네릭 제약 조건#

TypeScript
// T는 반드시 length 속성을 가져야 함
function getLength<T extends { length: number }>(item: T): number {
    return item.length;
}

getLength("hello");      // 5
getLength([1, 2, 3]);    // 3
// getLength(42);        // ❌ number는 length 없음

// keyof 제약
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key];
}

const user = { name: "철수", age: 25 };
getProperty(user, "name");   // "철수"
// getProperty(user, "email");  // ❌ 'email'은 키가 아님

제네릭 인터페이스와 타입#

TypeScript
// 제네릭 인터페이스
interface ApiResponse<T> {
    data: T;
    status: number;
    message: string;
}

interface User {
    id: number;
    name: string;
}

const userResponse: ApiResponse<User> = {
    data: { id: 1, name: "철수" },
    status: 200,
    message: "성공",
};

const listResponse: ApiResponse<User[]> = {
    data: [{ id: 1, name: "철수" }],
    status: 200,
    message: "성공",
};

제네릭 유틸리티 패턴#

TypeScript
// 페이지네이션 응답
interface Paginated<T> {
    items: T[];
    total: number;
    page: number;
    pageSize: number;
}

// 비동기 작업 상태
interface AsyncState<T> {
    data: T | null;
    loading: boolean;
    error: Error | null;
}

// 사용
type UserListState = AsyncState<User[]>;
const state: UserListState = {
    data: null,
    loading: true,
    error: null,
};

함수 오버로드#

같은 함수가 입력 타입에 따라 다른 타입을 반환할 때 사용합니다.

TypeScript
// 오버로드 시그니처
function parse(value: string): number;
function parse(value: number): string;
// 구현 시그니처
function parse(value: string | number): number | string {
    if (typeof value === "string") return parseInt(value);
    return value.toString();
}

const num = parse("42");    // number
const str = parse(42);      // string

실전: API 호출 래퍼#

TypeScript
async function fetchApi<T>(url: string): Promise<ApiResponse<T>> {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`HTTP error: ${response.status}`);
    }
    return response.json() as Promise<ApiResponse<T>>;
}

// 타입 안전한 API 호출
const userData = await fetchApi<User>("/api/users/1");
// userData.data: User 타입으로 추론
console.log(userData.data.name);

정리#

개념예시용도
함수 타입(a: number) => string함수 구조 정의
선택적 매개변수name?: string있어도 없어도 됨
제네릭<T>재사용 가능한 타입
제약 조건T extends X제네릭 범위 제한
keyofK extends keyof T객체 키 타입
오버로드시그니처 + 구현다형성 함수

다음 편에서는 클래스와 접근 제어자 — TypeScript로 객체지향 프로그래밍을 하는 방법을 배웁니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.