TypeScript 함수는 매개변수에, 그리고 선택적으로 반환값에 타입을 붙인 JavaScript 함수입니다. 모든 매개변수에 표기를 붙이고, 반환 타입은 매개변수 목록 뒤에 쓰며, 컴파일러는 모든 호출을 둘 다에 대해 검사합니다.
잘못된 호출 두 개는 모두 컴파일 오류(TS2345와 TS2554)입니다. // @ts-expect-error 주석은 다음 줄에 오류가 예상된다고 컴파일러에 알려 주므로 파일의 나머지는 그대로 실행됩니다. 둘 중 하나를 지우고 다시 실행해 실제 메시지를 확인해 보세요.
매개변수 타입
각 매개변수는 name: Type으로 씁니다. TypeScript 7에서 기본으로 켜져 있는 strict에서는 표기도 없고 추론할 문맥도 없는 매개변수가 오류입니다: Parameter 'x' implicitly has an 'any' type.(TS7006). 그래서 실제로는 독립된 함수의 모든 매개변수에 타입을 표기합니다.
원시 타입, 배열, 객체 타입, 유니언, 다른 함수 등 어떤 타입이든 매개변수 타입으로 쓸 수 있습니다.
TypeScript는 인수의 개수도 검사합니다. 선언보다 많거나 적게 넘기면 오류입니다. 빠진 인수를 undefined로 채우고 남는 인수는 무시하는 평범한 JavaScript와 다릅니다. 매개변수를 선택적으로 만들거나 기본값을 주려면 선택적 매개변수를 보세요.
반환 타입: 표기하거나 추론하거나
반환 타입은 닫는 괄호 뒤에 옵니다: function f(): Type. 선택 사항입니다. 없으면 TypeScript가 본문의 모든 return에서 타입을 추론합니다.
함수를 export할 때, 반환 경로가 여러 개일 때, 재귀일 때 표기가 제 몫을 합니다. 그러면 오류가 호출부가 아니라 함수 안의 잘못된 return에서 나타납니다. 대표적인 예가 반환을 잊은 분기입니다.
컴파일러는 index.ts(2,32): error TS2366: Function lacks ending return statement and return type does not include 'undefined'.를 보고합니다. 마지막에 return "C";를 더하면 실행됩니다. : string 표기가 없었다면 함수는 추론된 타입 "A" | "B" | undefined로 컴파일되고, 문제는 결과를 쓰는 쪽으로 옮겨 갔을 것입니다.
void: 아무것도 반환하지 않는 함수
무언가를 하기만 하는(로그를 남기거나, 쓰거나, 값을 바꾸는) 함수의 반환 타입은 void입니다. 값과 함께 쓰인 return이 없을 때 TypeScript가 추론하는 타입이며, 명시적으로 쓸 수도 있습니다.
void에 관한 다음 규칙은 사람들을 놀라게 합니다.
| 상황 | 허용되나? |
|---|---|
function f(): void { return 42; } | 아니요: Type 'number' is not assignable to type 'void'.(TS2322) |
const f: () => void = () => 42; | 예: 값은 반환되지만 호출하는 쪽이 기대면 안 됨 |
function f(): undefined {} | 예(TypeScript 5.1 이상) |
void 함수의 결과를 if에서 사용 | 아니요: An expression of type 'void' cannot be tested for truthiness.(TS1345) |
두 번째 행은 의도된 것입니다. push가 숫자를 반환하는데도 arr.forEach(x => list.push(x))가 컴파일되는 이유입니다. 함수 타입의 void는 "무엇을 반환하든 아무도 읽지 않는다"는 뜻입니다. 아예 반환하지 않는 함수(항상 예외를 던지거나 영원히 도는 함수)의 반환 타입은 never입니다.
화살표 함수와 함수 표현식
화살표 함수와 함수 표현식도 같은 표기를 받습니다. 반환 타입은 매개변수 목록 뒤, => 앞에 옵니다.
괄호가 없으면 (x, y) => { x, y }는 return이 없는 블록이 되어 함수가 undefined를 반환합니다. 화살표 함수의 런타임 규칙(자체 this가 없음, arguments가 없음)은 JavaScript와 같습니다. JavaScript의 화살표 함수를 참고하세요.
함수를 인수로 인라인 작성할 때는 보통 매개변수에 타입을 아예 표기하지 않습니다. 넘겨받는 함수에서 콜백이 무엇을 받는지 TypeScript가 압니다(문맥적 타이핑). [1, 2].map(n => n * 2)에서 n은 이미 number입니다. 함수의 타입을 값으로 쓰는 (n: number) => string은 함수 타입에서 다룹니다.
여러 값 반환하기
함수는 값 하나를 반환하므로, 객체나 튜플을 반환하고 구조 분해하세요.
튜플 반환 타입에는 표기가 필요합니다. 없으면 [a, b]는 string[]로 추론됩니다. 구조 분해는 여전히 되지만, 타입이 요소가 정확히 두 개라는 것을 더 이상 말하지 않습니다.
async 함수
async 함수는 항상 Promise를 반환합니다. 반환 타입을 Promise<T>로 표기하세요. T는 함수 안에서 반환하는 값입니다.
async function loadScore(id: number): Promise<number> {
await new Promise((resolve) => setTimeout(resolve, 10));
return id * 10;
}
async function main(): Promise<void> {
const score = await loadScore(4); // score: number
console.log("score", score);
}
main();
async function f(): number라고 쓰면 오류입니다: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'?(TS1064).
this 매개변수
JavaScript는 호출 시점에 this를 정합니다. TypeScript에서는 this라는 이름의 가짜 첫 번째 매개변수로 this가 무엇이어야 하는지 선언할 수 있습니다. 이 매개변수는 컴파일된 JavaScript에서 제거되고 호출하는 쪽은 넘기지 않습니다.
interface Counter {
count: number;
}
function increment(this: Counter, by: number): void {
this.count += by;
}
const c = { count: 0, increment };
c.increment(2); // fine: this is c
increment(2);
// error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.
this 매개변수가 없으면 독립된 함수 안의 this는 암묵적 any이고, strict 모드는 'this' implicitly has type 'any' because it does not have a type annotation.(TS2683)을 보고합니다. 클래스 메서드에서 this는 이미 클래스 인스턴스로 타입이 지정되므로, 이 매개변수는 주로 객체에 붙이는 독립 함수와 라이브러리가 특정 this로 호출하는 콜백에 유용합니다.
자주 묻는 질문
TypeScript에서 함수 반환 타입은 어떻게 지정하나요?
매개변수 목록 뒤에 콜론과 타입을 씁니다: function total(a: number, b: number): number { ... }. 화살표 함수도 같은 자리에 씁니다: const total = (a: number, b: number): number => a + b;. 생략하면 TypeScript가 return 문에서 반환 타입을 추론합니다.
TypeScript에서 반환 타입을 항상 표기해야 하나요?
반환 타입은 추론되므로 선택 사항입니다. export하는 함수와 return 경로가 여러 개인 함수에는 표기하세요. 표기가 계약을 문서화하고, 잘못된 return이 멀리 떨어진 호출부가 아니라 함수 안에서 보고됩니다.
TypeScript에서 void와 undefined의 차이는 무엇인가요?
void는 "호출하는 쪽이 반환값을 쓰면 안 된다"는 뜻입니다. undefined는 구체적인 값 타입입니다. (): void로 선언한 함수는 값을 반환할 수 없지만, 콜백 타입 () => void는 무언가를 반환하는 함수도 받아들이고 결과는 그냥 무시됩니다. 아무것도 반환하지 않는 함수에는 void를 쓰고, 호출하는 쪽이 정말로 결과를 undefined와 비교할 때만 undefined를 쓰세요.
TypeScript 함수에서 여러 값을 반환하려면 어떻게 하나요?
객체({ min: number; max: number })나 튜플([number, number])을 반환하고 호출하는 곳에서 구조 분해하세요. 값들의 의미가 서로 다르면 객체가 더 명확하고, [value, setValue] 같은 짧은 쌍에는 튜플이 잘 읽힙니다.
TypeScript에서 async 함수의 반환 타입은 무엇인가요?
항상 Promise입니다. number를 반환하는 async 함수의 반환 타입은 Promise<number>이고, 여기에 : number라고 쓰면 컴파일 오류(TS1064)입니다. 아무것도 반환하지 않는 함수는 Promise<void>입니다.