icon
3장 : 함수와 타입

함수 타입 정의


프로그래밍에서 함수(Function) 는 특정 작업을 수행하는 코드 블록이자, 프로그램의 핵심적인 구성 요소입니다. 자바스크립트에서 함수는 일급 객체(First-class Citizen)로서, 변수에 할당되거나 다른 함수의 인자로 전달될 수 있는 등 매우 유연하게 사용됩니다. 타입스크립트는 이러한 함수의 유연성을 유지하면서도, 함수를 더욱 안전하고 예측 가능하게 만들 수 있는 강력한 함수 타입 정의 기능을 제공합니다.

이 절에서는 타입스크립트에서 함수를 어떻게 타입 안전하게 정의하고 사용하는지, 그리고 함수의 매개변수와 반환 값에 타입을 부여하는 다양한 방법에 대해 자세히 알아보겠습니다.


함수의 기본 타입 정의

가장 기본적인 함수 타입 정의는 함수의 매개변수(Parameters)반환 값(Return Type) 에 타입을 명시하는 것입니다. 이는 함수가 어떤 종류의 입력을 받아 어떤 종류의 출력을 내보낼지 명확히 선언하는 것과 같습니다.

// 1. 매개변수와 반환 값에 타입 명시
function add(x: number, y: number): number {
  return x + y;
}

// 2. 반환 값이 없는 함수 (void)
function logMessage(message: string): void {
  console.log(message);
}

// 3. 함수 표현식에 타입 정의
const subtract = function(a: number, b: number): number {
  return a - b;
};

// 4. 화살표 함수에 타입 정의
const multiply = (a: number, b: number): number => {
  return a * b;
};

console.log(add(10, 5));        // 15
logMessage("TypeScript 함수 타입 학습"); // TypeScript 함수 타입 학습
console.log(subtract(20, 7));   // 13
console.log(multiply(3, 4));    // 12

// 오류 예시: 잘못된 타입의 인자 전달
// add("hello", 5); // Error: 'string' 형식의 인수는 'number' 형식의 매개 변수에 할당될 수 없습니다.

// 오류 예시: 잘못된 반환 타입
// function invalidReturn(): number {
//   return "이것은 숫자가 아닙니다."; // Error: 'string' 형식은 'number' 형식에 할당될 수 없습니다.
// }

위 예시에서 핵심은 다음과 같습니다.

  • 매개변수 타입: 매개변수 이름 뒤에 콜론(:)을 붙이고 해당 매개변수가 받을 값의 타입을 명시합니다. (x: number)
  • 반환 타입: 매개변수 목록 괄호 뒤에 콜론(:)을 붙이고 함수가 반환할 값의 타입을 명시합니다. (): number)
  • 반환 값이 없는 함수는 void 타입을 반환 타입으로 사용합니다.

선택적 매개변수

자바스크립트에서는 함수를 호출할 때 매개변수를 생략할 수 있습니다. 타입스크립트에서도 특정 매개변수가 필수적이지 않고 선택적으로 전달될 수 있도록 할 수 있습니다. 매개변수 이름 뒤에 물음표(?)를 붙여 선택적 매개변수로 만듭니다.

function buildName(firstName: string, lastName?: string): string {
  if (lastName) {
    return firstName + " " + lastName;
  } else {
    return firstName;
  }
}

let result1 = buildName("김");        // 김
let result2 = buildName("이", "철수"); // 이 철수
// let result3 = buildName("박", "영희", "씨"); // Error: 예상되는 인수는 1-2개이지만 3개를 가져왔습니다.

console.log(result1);
console.log(result2);

주의할 점: 선택적 매개변수는 항상 필수 매개변수 뒤에 위치해야 합니다. 즉, (arg1?: type, arg2: type)과 같은 형태는 허용되지 않습니다.


기본 매개변수

ES6부터 자바스크립트에서는 함수 매개변수에 기본 값(Default Value) 을 설정할 수 있게 되었습니다. 타입스크립트에서도 이 기능을 지원하며, 기본 값을 가진 매개변수는 자동으로 선택적 매개변수로 간주됩니다.

function greet(name: string = "게스트"): string {
  return `안녕하세요, ${name}님!`;
}

console.log(greet("김아영")); // 안녕하세요, 김아영님!
console.log(greet());         // 안녕하세요, 게스트님! (매개변수를 생략하면 기본값이 사용됨)

// 기본 매개변수는 선택적 매개변수와 유사하게 동작합니다.
// 그러나 기본 매개변수 뒤에 필수 매개변수를 배치할 수도 있습니다.
function sendEmail(to: string, subject: string = "제목 없음", body: string): void {
    console.log(`To: ${to}, Subject: ${subject}, Body: ${body}`);
}

// sendEmail("user@example.com", "안녕하세요"); // Error: 'body' 매개 변수에 대한 인수가 없습니다.
sendEmail("user@example.com", undefined, "반갑습니다."); // body는 필수이므로 정의해야 합니다.
sendEmail("another@example.com", "안부 인사", "잘 지내시죠?");

기본 매개변수는 함수 호출 시 해당 인자를 제공하지 않으면 지정된 기본 값을 사용하므로, 함수의 유연성을 높이면서도 예상치 못한 undefined 값을 다루는 경우를 줄여줍니다.


나머지 매개변수

함수가 정해지지 않은 수의 인자를 받을 때, 자바스크립트의 나머지 매개변수(Rest Parameters) 문법을 사용할 수 있습니다. 타입스크립트에서는 나머지 매개변수에 배열 타입을 명시하여, 해당 인자들이 모두 동일한 타입임을 보장할 수 있습니다.

function sumAll(...numbers: number[]): number {
  let total = 0;
  for (let i = 0; i < numbers.length; i++) {
    total += numbers[i];
  }
  return total;
}

console.log(sumAll(1, 2, 3));         // 6
console.log(sumAll(10, 20, 30, 40));  // 100

// 오류 예시: 배열의 요소 타입이 맞지 않습니다.
// console.log(sumAll(1, 2, "3")); // Error: 'string' 형식의 인수는 'number' 형식의 매개 변수에 할당될 수 없습니다.

나머지 매개변수는 항상 함수 선언의 가장 마지막 매개변수여야 하며, 배열 타입으로 정의됩니다. 스프레드 연산자(...)와 함께 사용되어 전달된 여러 인자들을 하나의 배열로 묶어줍니다.


함수 타입 별칭

복잡하거나 반복적으로 사용되는 함수 타입이 있다면, 타입 별칭(Type Aliases) 을 사용하여 함수 자체의 타입을 정의할 수 있습니다. 이는 코드의 가독성을 높이고, 동일한 형태의 함수를 여러 곳에서 사용할 때 유용합니다.

// AddFunction이라는 함수 타입 별칭을 정의합니다.
// 이 타입은 두 개의 number 타입 매개변수를 받고 number 타입을 반환하는 함수를 의미합니다.
type AddFunction = (a: number, b: number) => number;

let myAdd: AddFunction = function(x, y) {
  return x + y;
};

let myMultiply: AddFunction = (x, y) => x * y;

console.log(myAdd(5, 7));       // 12
console.log(myMultiply(5, 7));  // 35

// 오류 예시: 정의된 함수 타입과 반환 타입이 다릅니다.
// let myInvalidAdd: AddFunction = (x, y) => "결과: " + (x + y);
// Error: 'string' 형식은 'number' 형식에 할당될 수 없습니다.

// 매개변수 타입은 추론되므로 생략 가능합니다.
// let anotherAdd: AddFunction = (x, y) => x + y; // x와 y는 number로 추론됩니다.

type AddFunction = (a: number, b: number) => number;와 같이 정의하며, 이는 마치 함수가 변수처럼 취급되어 특정 형태를 따르도록 강제하는 것과 같습니다.


함수 타입 정의는 타입스크립트의 핵심적인 부분입니다. 함수의 매개변수와 반환 값에 명확한 타입을 부여함으로써, 개발 과정에서 발생할 수 있는 많은 오류를 사전에 방지하고 코드의 신뢰성을 높일 수 있습니다. 또한, 선택적 매개변수, 기본 매개변수, 나머지 매개변수, 그리고 함수 타입 별칭을 통해 더욱 유연하고 가독성 높은 함수를 작성할 수 있게 됩니다.