[Typescript] 함수 사용하기 (parameter, optional, rest, overloading)

1. 함수 선언
• 매개변수와 리턴값의 타입을 선언 후 사용하면 된다.
function func1(name: string): string {
return 'hello ${name}';
}
const func2 = function (name: string): string {
return 'hello ${name}';
}
const func3 = (name: string): string => {
return 'hello ${name}';
}
const world4 = (name: string): string => 'hello ${name}';
2. 매개변수 수 일치
• 함수에 주어진 인자의 수는 함수가 기대하는 매개변수의 수와 일치해야 한다.
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
const result1 = buildName("Bob"); // Error: Expected 2 arguments, but got 1
const result2 = buildName("Bob", "Adams", "Sr."); // Error: Expected 2 arguments, but got 3
const result3 = buildName("Bob", "Adams")
3. Optional Parameter
• ?를 붙여 선택적 프로퍼티를 만들수도 있다.
• 선택적 매개변수들은 필수 매개변수 뒤에 위치해야한다.
function buildName(firstName: string, lastName?: string) {
if (lastName) return firstName + " " + lastName;
else return firstName;
}
let result1 = buildName("Bob");
let result2 = buildName("Bob", "Adams");
let result3 = buildName("Bob", "Adams", "Sr."); // Error: Expected 2 arguments, but got 3
4. Rest Parameter
• 컴파일러는 생략 부호(...) 뒤의 인자 배열을 빌드해 함수에서 사용할 수 있다.
• 나머지 매개변수는 매개변수의 수를 무한으로 취급한다.
• 아무것도 넘겨주지 않을 수도 있다.
function buildName1(firstName: string, ...restOfName: string[]) {
// restOfName = [ 'Samuel', 'Lucas', 'MacKinzie' ]
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName1("Joseph", "Samuel", "Lucas","MacKinzie");
// "Joseph Samuel Lucas MacKinzie"
5. Function Overloading
• 파라미터의 형태가 여러 케이스에 대응하는 같은 이름을 가진 함수를 만들 때 사용한다.
• 함수의 다형성(다양한 형태)을 지원한다.
함수 오버로딩을 위해 해야할 것 2가지
-
선언 : 함수가 어떤 파라미터 타입들을 다룰 것인지 선언
-
구현 : 각 파라미터 타입에 대응하는 구체적인 코드를 작성
1. 함수 오버로딩 선언
- 함수의 이름이 같아야 한다.
- 매개변수의 순서는 서로 같아야 한다.
- 반환 타입이 같아야 한다.
class User { // ✅
constructor(private id: string) {}
setId(id: string): string;
setId(id: number): string;
}
class User { // ❌
constructor(private id: string) {}
// 선언 시에 에러는 나지 않지만 오버로딩 함수 정의 시에 에러;
setId(id: string): void;
setId(id: string): number; // 반환 타입 다름;
setId(radix: number, id: number): void; // 인수 순서 다름
}
2. 함수 오버로딩 구현
1) 매개변수의 개수가 같을 때
class User {
constructor(private id: string) {}
setId(id: string): void;
setId(id: number): void;
setId(id: string | number): void {
this.id = typeof id === 'number' ? id.toString() : id;
}
}
2) 매개변수의 개수가 다를 때
class User {
constructor(private id: string) {}
setId(id: string): void;
setId(id: number, radix: number): void;
setId(id: string | number, radix?: number): void {
this.id = typeof id === 'number' ? id.toString(radix) : id;
}
}
3. 함수 오버로딩으로 바꾼 예시
Before
- 파라미터의 타입만 다르고 비슷한 코드가 반복되고 있는 코드에서 함수 오버로딩을 적용해보자
const addZero = (num: string) => (num > 9 ? '' : '0') + num;
function formatDate(date: Date, format = 'yyyyMMdd'): string {
const yyyy = date.getFullYear().toString();
const MM = addZero(date.getMonth() + 1);
const dd = addZero(date.getDate());
return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}
function formatDateString(dateStr: string, format = 'yyyyMMdd'): string {
const date = new Date(dateStr);
const yyyy = date.getFullYear().toString();
const MM = addZero(date.getMonth() + 1);
const dd = addZero(date.getDate());
return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}
function formatDateTime(datetime: string, format = 'yyyyMMdd'): string {
const date = new Date(datetime);
const yyyy = date.getFullYear().toString();
const MM = addZero(date.getMonth() + 1);
const dd = addZero(date.getDate());
return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}
After
const addZero = (num: string) => (num > 9 ? '' : '0') + num;
function formatDate(date: Date, format = 'yyyyMMdd'): string;
function formatDate(date: number, format = 'yyyyMMdd'): string;
function formatDate(date: string, format = 'yyyyMMdd'): string;
function formatDate(date: string | Date | number, format = 'yyyyMMdd'): string {
const dateToFormat = new Date(date);
// … dateToFormat validation …
const yyyy = dateToFormat.getFullYear().toString();
const MM = addZero(dateToFormat.getMonth() + 1);
const dd = addZero(dateToFormat.getDate());
return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}
4. 제네릭과 차이점
| 타입 추론 시점 | 용도의 범위 | |
| 제네릭 | 타입이 사용되는 시점 | 제네릭 타입 인터페이스 클래스 함수 등 |
| 함수 오버로딩 | 타입을 선언하는 시점 | 함수 메서드 |