[TypeScript] 타입스크립트 함수 오버로딩 : Function Overloading
글 작성자: 망고좋아
반응형
🎯 타입스크립트 함수 오버로딩 : Function Overloading
- 동일한 이름에 매개 변수만 다른 여러 버전의 함수를 만드는 것을 함수의 오버로딩이라고 한다.
- 파라미터의 형태가 다양한 여러 케이스에 대응하는 같은 이름을 가진 함수를 만드는 것
- 함수의 다형성(다양한 형태)을 지원하는 것
- function 키워드로만 함수 오버로딩을 할 수 있으며 arrow function으로는 오버로딩을 할 수 없다.
📝 Function Overloading는 언제 사용할 수 있을까?
const addZero = (num: number) => (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: number, 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);
}
- 파라미터만 달라지고, 비슷한 로직이 반복되는 경우에 사용할 수 있다.
- 코드의 중복을 줄이고 재사용성을 높이려면 어떻게 해야 할까? ⇒ Function Overloading
📝 함수 오버로딩을 위해 해야 할 것 2가지
- 선언 : 함수가 어떤 파라미터 타입들을 다룰 것인지 선언
- 구현 : 각 파라미터 타입에 대응하는 구체적인 코드를 작성(ex. string일 때는 ~~, number일 때 ~~)
📝 함수 오버로딩 선언할 시 주의할 점
- 함수의 이름은 같아야 한다.
- 매개변수의 순서는 서로 같아야 한다. (매개변수가 추가되는 것은 괜찮다! 순서는 꼭 지켜줘야 된다.)
// 문제 없는 함수 오버로딩 선언
class User {
constructor(private id: string) {}
setId(id: string): string;
setId(id: number): string;
}
// Error
class User {
constructor(private id: string) {}
// 선언 시에 에러는 나지 않지만 오버로딩 함수 정의 시에 에러
setId(id: string): void;
setId(id: string): number; // 반환 타입 다름
setId(radix: number, id: number): void; // 인수 순서 다름
}
📝 함수 오버로딩 구현
📕 매개변수의 개수가 같을 때
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; // 타입 가드
}
}
📕 매개변수의 개수가 다를 때
class User {
constructor(private id: string) {}
setId(id: string): void;
setId(id: number, radix: number): void;
// 유니온 타입으로 선언 & 옵셔널 & 타입 가드
setId(id: string | number, radix?: number): void { // radix는 number or undefined
this.id = typeof id === "number" ? id.toString(radix) : id;
}
}
📝 함수 오버로딩 예제
📕 리팩토링 전
const addZero = (num: number) => (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: number, 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);
}
📕 함수 오버로딩으로 리팩토링
const addZero = (num: number) => (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;
// 위 3개 함수를 함수 오버로딩 처리, date는 유니온 타입사용
function formatDate(date: string | Date | number, format = "yyyyMMdd"): string {
const dateToFormat = new Date(date);
// … dateToFormat validation … 만약 empty나 1, 0이 들어왔을 때 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);
}
📕 또 다른 예
class User {
// 생성자 안에서 접근 제한자 키워드가 있다면 파라미터로 넘기는 동시에 할당(this.id = id)해준다.
constructor(public id?: string) {}
// 선언
setId(id: string): void;
setId(id: number): void;
// 구현
setId(id: string | number): void {
// 구현 내용
this.id = typeof id === 'number' ? id.toString() : id
}
}
const elice = new User();
elice.setId(12345);
console.log(elice.id, typeof elice.id);
elice.setId("123");
console.log(elice.id, typeof elice.id);
constructor(public id?: string) {}
는 생성자 안에서 접근 제한자 키워드가 있다면 파라미터로 넘기는 동시에 할당(this.id = id)해준다.
📝 제네릭과의 차이점
- 타입을 추론할 수 있는 시점과 용도의 범위
타입 추론 시점 | 용도의 범위 | |
제네릭 | 사용되는 시점 | 제네릭 타입, 인터페이스, 클래스, 함수, 메서드 등 |
함수 오버로딩 | 타입을 선언하는 시점 | 함수, 메서드 |
- 함수 파라미터에 들어갈 타입을 알고 있고, 파라미터 타입만 달라지고 함수의 로직이 반복된다면 함수 오버로딩 사용
- 어떤 타입이 올지 모르겠고, 타입을 다양한 용도에서 사용하고 싶다면 제네릭 사용
반응형
'프로그래밍 > TypeScript' 카테고리의 다른 글
[TypeScript] 타입스크립트 인덱스 시그니처 (Index Signature) (0) | 2021.11.29 |
---|---|
[TypeScript] 타입스크립트 타입 단언 (Type Assertion) (0) | 2021.11.29 |
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator) (1) | 2021.11.29 |
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining) (0) | 2021.11.29 |
[TypeScript] 타입스크립트 타입 가드 (Type Guard) (0) | 2021.11.29 |
댓글
이 글 공유하기
다른 글
-
[TypeScript] 타입스크립트 인덱스 시그니처 (Index Signature)
[TypeScript] 타입스크립트 인덱스 시그니처 (Index Signature)
2021.11.29 -
[TypeScript] 타입스크립트 타입 단언 (Type Assertion)
[TypeScript] 타입스크립트 타입 단언 (Type Assertion)
2021.11.29 -
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
2021.11.29 -
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
2021.11.29