Adventure Time - Finn 3
본문 바로가기
프론트

TypeScript 함수 타입

by hyun9_9 2026. 4. 11.

함수의 매개변수와 반환값에 타입을 지정하는 기본기부터, 오버로드까지 단계별로 정리합니다.


1. 함수의 반환 타입 지정

함수 선언 시 괄호 뒤에 반환 타입을 명시합니다. 명시한 타입과 실제 반환값이 다르면 컴파일 에러가 발생합니다.

// number를 반환
function add1(num1: number, num2: number): number {
  return num1 + num2;
}

// 반환값이 없는 함수
function add2(num1: number, num2: number): void {
  console.log(num1 + num2);
}

// boolean을 반환
function isAdult(age: number): boolean {
  return age > 19;
}

⚠️ 반환 타입을 number로 지정해놓고 아무것도 return하지 않으면 에러가 발생합니다. 반환값이 없다면 void를 사용하세요.


2. 선택적 매개변수 (?)

매개변수에 ?를 붙이면 해당 인자를 넘기지 않아도 됩니다.

function hello(name?: string): string {
  return `Hello, ${name || "world"}`;
}

hello();        // "Hello, world"
hello("Sam");   // "Hello, Sam"

name이 전달되지 않으면 undefined가 되므로, 기본값 처리를 함께 해주는 것이 안전합니다.

기본값으로 대체하기

? 대신 매개변수에 직접 기본값을 넣을 수도 있습니다. 이 경우 타입은 기본값에서 자동 추론됩니다.

function hello2(name = "world"): string {
  return `Hello, ${name}`;
}

hello2();        // "Hello, world"
hello2("Sam");   // "Hello, Sam"

3. 선택적 매개변수의 위치 주의점

선택적 매개변수는 반드시 필수 매개변수 뒤에 와야 합니다. 앞에 두면 에러가 발생합니다.

// ❌ Error — 선택적 매개변수가 필수 매개변수 앞에 있음
function hello3(age?: number, name: string): string {
  if (age !== undefined) {
    return `Hello, ${name}. You are ${age}`;
  }
  return `Hello, ${name}`;
}

만약 선택적 매개변수를 앞에 두고 싶다면, ? 대신 유니온 타입으로 undefined를 명시적으로 허용합니다.

// ✅ OK — undefined를 명시적으로 허용
function hello3(age: number | undefined, name: string): string {
  if (age !== undefined) {
    return `Hello, ${name}. You are ${age}`;
  }
  return `Hello, ${name}`;
}

hello3(undefined, "Sam");  // "Hello, Sam"
hello3(30, "Sam");          // "Hello, Sam. You are 30"

💡 ?는 "안 넘겨도 된다"는 의미이고, number | undefined는 "반드시 넘기되 undefined도 허용한다"는 의미입니다. 호출 시 인자 생략 가능 여부에 차이가 있습니다.


4. 나머지 매개변수 (Rest Parameters)

매개변수 개수가 유동적일 때 ... 스프레드 문법으로 배열 타입을 지정합니다.

function add(...nums: number[]) {
  return nums.reduce((result, num) => result + num, 0);
}

add(1, 2, 3);                    // 6
add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  // 55

nums는 전달된 모든 인자를 number[] 배열로 받아 처리합니다.


5. this 타입 지정

TypeScript에서는 함수의 첫 번째 매개변수 위치에 this의 타입을 명시할 수 있습니다. 이 매개변수는 실제로 전달하는 인자가 아니라, this가 어떤 타입인지 컴파일러에게 알려주는 역할입니다.

interface User {
  name: string;
}

const Sam: User = { name: 'Sam' };

function showName(this: User, age: number, gender: 'm' | 'f') {
  console.log(this.name, age, gender);
}

const a = showName.bind(Sam);
a(30, 'm');  // "Sam" 30 "m"

💡 this: User는 호출 시 넘기는 인자가 아닙니다. bind, call, apply로 바인딩된 this의 타입을 검사하기 위한 TypeScript 전용 문법입니다.


6. 함수 오버로드 (Function Overload)

전달받은 매개변수의 타입이나 개수에 따라 다른 반환 타입을 가져야 할 때 사용합니다.

문제 상황

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

function join(name: string, age: number | string): User | string {
  if (typeof age === "number") {
    return { name, age };
  } else {
    return "나이는 숫자로";
  }
}

const sam: User = join("Sam", 30);     // ❌ Error — User | string을 User에 할당 불가
const jane: string = join("Jane", "30"); // ❌ Error — User | string을 string에 할당 불가

함수 내부 로직상 age가 number면 User를, string이면 string을 반환하지만, TypeScript는 반환 타입을 User | string으로밖에 추론하지 못합니다.

오버로드로 해결

함수 본체 위에 오버로드 시그니처를 선언하면, 입력 타입에 따라 반환 타입을 정확히 매핑할 수 있습니다.

function join(name: string, age: number): User;      // 시그니처 1
function join(name: string, age: string): string;     // 시그니처 2
function join(name: string, age: number | string): User | string {
  if (typeof age === "number") {
    return { name, age };
  } else {
    return "나이는 숫자로";
  }
}

const sam: User = join("Sam", 30);       // ✅ OK — number를 넘기면 User 반환
const jane: string = join("Jane", "30"); // ✅ OK — string을 넘기면 string 반환

💡 오버로드 시그니처는 실제 구현이 아닌 타입 정보만 제공합니다. 마지막에 오는 구현부가 모든 시그니처를 포괄할 수 있어야 합니다.


한눈에 보기

기능 문법 설명

반환 타입 function fn(): number 반환값의 타입 명시
void function fn(): void 반환값 없음
선택적 매개변수 name?: string 인자 생략 가능
기본값 name = "world" 생략 시 기본값 사용
유니온 허용 age: number | undefined 앞쪽에 선택적 매개변수 배치 시
나머지 매개변수 ...nums: number[] 가변 인자를 배열로 수집
this 타입 this: User this의 타입 명시 (실제 인자 아님)
오버로드 시그니처 + 구현부 입력에 따라 반환 타입 분기