함수를 설명하는 가장 좋은 방법
- JavaScript(JS) : 어떤 매개변수를 받고, 어떤 결과값을 반환하는지 이야기
- TypeScript(TS) : 어떤 '타입의' 매개변수를 받고, 어떤 '타입의' 결과값을 반환하는지 이야기
function add(a: number, b: number): number {
return a + b;
}
a와 b의 타입이 number이며, 반환값(return)의 타입도 number로 지정됨.function add(a: number, b: number) {
return a + b; // 반환값의 타입을 자동으로 number로 추론
}
return문을 기준으로 자동 추론한다.const add = function (a: number, b: number): number {
return a + b;
};
add에 익명 함수를 할당하는 방식const add: (a: number, b: number) => number = function (a, b) {
return a + b;
};
const add = (a: number, b: number): number => a + b;
const add = (a: number, b: number) => a + b; // 반환값을 number로 추론
객체를 반환하는 경우는 주의가 필요하다.
const makeUser = (name: string, age: number) => { name, age }; // 오류 발생!
{}는 함수 블록으로 인식되므로 return이 없다고 간주된다.const makeUser = (name: string, age: number) => ({ name, age }); // 객체 반환
반복되는 함수 타입을 별칭으로 정의하여 사용할 수 있다.
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
인터페이스를 사용하여 함수 타입을 정의할 수도 있다.
interface Add {
(a: number, b: number): number;
}
const add: Add = (a, b) => a + b;
type과 interface 모두 함수 타입을 정의할 수 있지만,
interface는 객체 타입과 함께 사용할 수도 있으며 extends로 확장 가능하다.
매개변수에 기본값을 설정하면, 타입을 직접 정의하지 않아도 기본값을 기준으로 자동 추론된다.
function introduce(name = "띠닝") {
console.log(`name: ${name}`);
}
function introduce(name: number = "띠닝") {
// ❌ Type 'string' is not assignable to type 'number'.
console.log(`name: ${name}`);
}
function introduce(name = "띠닝") {
console.log(`name: ${name}`);
}
introduce(1); // ❌ Argument of type 'number' is not assignable to parameter of type 'string'.
매개변수를 생략하고 싶다면 선택적 매개변수를 사용할 수 있다.
function introduce(name = "띠닝", tall?: number) {
console.log(`name: ${name}`);
// 타입 좁히기 (tall은 number 또는 undefined 이므로, typeof 체크)
if (typeof tall === "number") {
console.log(`tall: ${tall + 10}`);
}
}
introduce("띠닝", 170);
introduce("띠닝"); // 선택적 매개변수 생략 가능
?를 붙여서 정의한다.선택적 매개변수는 필수 매개변수 앞에 올 수 없다.
function greet(age?: number, name: string) {
// ❌ 'age' is declared before required parameter 'name'.
console.log(`${name}의 나이는 ${age}세 입니다.`);
}
function greet(name: string, age?: number) {
console.log(`${name}의 나이는 ${age ?? "모름"}세 입니다.`);
}
나머지 매개변수를 사용하면 여러 개의 값을 배열로 받을 수 있다.
function getSum(...numbers: number[]): number {
return numbers.reduce((sum, num) => sum + num, 0);
}
console.log(getSum(1, 2, 3)); // 6
console.log(getSum(1, 2, 3, 4, 5)); // 15
나머지 매개변수는 반드시 마지막에 위치해야 한다.
function wrongFunc(...rest: number[], a: number) {
// ❌ A rest parameter must be last in a parameter list.
return rest;
}
function correctFunc(a: number, ...rest: number[]) {
return rest;
}
this 타입 지정TypeScript에서는 this의 타입을 명시적으로 지정할 수 있다.
interface User {
name: string;
getName(this: User): string;
}
const user: User = {
name: "띠닝",
getName() {
return this.name;
},
};
console.log(user.getName()); // "띠닝"
this의 타입을 올바르게 지정하지 않으면 strict 모드에서 오류가 발생할 수 있다.function sayHello(this: void) {
console.log("Hello!");
}
this: void로 지정하면, 해당 함수가 this에 의존하지 않음을 명시적으로 나타낼 수 있다.