함수 타입 — 매개변수, 반환값, 오버로드, this 타입
TypeScript에서 함수 타입이란 매개변수의 타입 과 반환값의 타입 을 명시하는 것입니다.
기본적인 함수 타입
// 함수 선언문
function add(a: number, b: number): number {
return a + b;
}
// 화살표 함수
const multiply = (a: number, b: number): number => a * b;
// 반환 타입 추론 — 명시하지 않아도 number로 추론됨
const subtract = (a: number, b: number) => a - b;
함수 타입 별칭
// 타입으로 함수 시그니처를 정의
type MathOperation = (a: number, b: number) => number;
const divide: MathOperation = (a, b) => a / b;
const modulo: MathOperation = (a, b) => a % b;
호출 시그니처(Call Signature)
// 함수이면서 속성도 가진 타입을 정의할 때
type DescribableFunction = {
description: string;
(arg: number): boolean; // 호출 시그니처
};
function isEven(n: number): boolean {
return n % 2 === 0;
}
(isEven as DescribableFunction).description = '짝수 판별';
선택적 매개변수와 기본값
// 선택적 매개변수 — ?를 붙이면 생략 가능
function greet(name: string, greeting?: string): string {
return `${greeting ?? '안녕하세요'}, ${name}님!`;
}
greet('홍길동'); // '안녕하세요, 홍길동님!'
greet('홍길동', '반갑습니다'); // '반갑습니다, 홍길동님!'
// 기본값이 있으면 ?를 안 붙여도 생략 가능
function greetWithDefault(name: string, greeting: string = '안녕하세요'): string {
return `${greeting}, ${name}님!`;
}
선택적 매개변수는 반드시 필수 매개변수 뒤에 와야 합니다.
나머지 매개변수(Rest Parameters)
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
// 튜플과 조합
function log(message: string, ...values: [number, boolean]): void {
console.log(message, ...values);
}
log('결과:', 42, true);
void와 never 반환 타입
// void: 반환값이 없음 (undefined 반환)
function logMessage(msg: string): void {
console.log(msg);
// return undefined; // OK
}
// never: 함수가 절대 정상적으로 종료되지 않음
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {
// 영원히 실행
}
}
면접 포인트:
void와never의 차이를 물어봅니다.void는 "반환값을 사용하지 않겠다"는 의미이고,never는 "이 함수는 정상적으로 끝나지 않는다"는 의미입니다.
함수 오버로드(Function Overload)
같은 함수 이름으로 ** 다른 매개변수 조합 **을 처리할 때 사용합니다.
// 오버로드 시그니처
function createElement(tag: 'div'): HTMLDivElement;
function createElement(tag: 'input'): HTMLInputElement;
function createElement(tag: 'a'): HTMLAnchorElement;
// 구현 시그니처
function createElement(tag: string): HTMLElement {
return document.createElement(tag);
}
// 호출할 때 정확한 반환 타입을 얻음
const div = createElement('div'); // HTMLDivElement
const input = createElement('input'); // HTMLInputElement
오버로드 작성 규칙
// ✅ 오버로드 시그니처는 구현 시그니처보다 위에 선언
function format(value: string): string;
function format(value: number): string;
function format(value: string | number): string {
if (typeof value === 'string') {
return value.trim();
}
return value.toFixed(2);
}
// ❌ 구현 시그니처는 직접 호출할 수 없음
// format(true); // Error — boolean을 받는 오버로드가 없음
공부하다 보니 오버로드보다 ** 제네릭이나 유니온 **으로 해결할 수 있는 경우가 많더라고요. 오버로드는 매개변수 타입에 따라 반환 타입이 달라지는 경우에만 사용하는 것이 좋습니다.
this 타입
// 메서드에서 this 타입을 명시
interface User {
name: string;
greet(this: User): string;
}
const user: User = {
name: '홍길동',
greet() {
return `안녕, ${this.name}`; // this가 User로 타입 체크됨
},
};
// ❌ this 컨텍스트가 깨지면 에러
// const greetFn = user.greet;
// greetFn(); // Error: The 'this' context is not assignable
메서드 체이닝에서 this 타입
class QueryBuilder {
private filters: string[] = [];
where(condition: string): this {
this.filters.push(condition);
return this; // this를 반환 타입으로 — 서브클래스에서도 체이닝 가능
}
build(): string {
return this.filters.join(' AND ');
}
}
class AdvancedQueryBuilder extends QueryBuilder {
orderBy(field: string): this {
// where()가 AdvancedQueryBuilder를 반환하므로 체이닝 가능
return this;
}
}
const query = new AdvancedQueryBuilder()
.where('age > 18') // AdvancedQueryBuilder 반환
.orderBy('name') // AdvancedQueryBuilder 반환
.where('active = true')
.build();
콜백 함수의 타입
// 콜백 타입 정의
type Callback = (error: Error | null, data?: string) => void;
function fetchData(url: string, callback: Callback): void {
try {
const data = '결과 데이터';
callback(null, data);
} catch (e) {
callback(e as Error);
}
}
// 콜백의 반환 타입은 보통 void
// void 반환 타입은 반환값이 있어도 무시됨
type VoidCallback = () => void;
const cb: VoidCallback = () => 42; // OK — 반환값은 무시됨
정리
- 함수 매개변수는 반드시 타입을 명시해야 하고, 반환 타입은 추론 가능하다
?로 선택적 매개변수, 기본값으로=을 사용한다void는 반환값 없음,never는 정상 종료 불가를 의미한다- 오버로드는 매개변수에 따라 반환 타입이 달라질 때만 사용한다
this타입으로 메서드 체이닝의 타입 안전성을 확보할 수 있다
댓글 로딩 중...