[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🎯 타입스크립트 인덱스 시그니처 (Index Signature) 📝 자바스크립트 Index Signature const dog = { breed: "retriever", name: "elice", bark: () => console.log("woof woof"), }; dog["breed"]; // value의 key인 breed 문자열로 객체의 value 접근 => 'retriever' 객체의 특정 value에 접근할 때 그 value의 key를 문자열로 인덱싱해 참조하는 방법 📝 타입스크립트 Index Signature interface Dictionary { [key: number]: T; } let keys: keyof Dictionary; // 숫자 let value: Dictionary['fo… -
[TypeScript] 타입스크립트 타입 단언 (Type Assertion)
[TypeScript] 타입스크립트 타입 단언 (Type Assertion)
2021.11.29🎯 타입스크립트 타입 단언 (Type Assertion) 타입스크립트가 추론하지 못하는 타입을 as키워드를 통해 명시해주는 것 사용법 : 변수 as 타입 chaining 하는 경우 변수를 괄호로 감싼 뒤 그 안에서 as 키워드를 사용 as뒤에 명시하고자 하는 데이터 타입을 작성해주면 된다. 실제 데이터 타입을 변경하지 않고 타입 에러가 나지 않게끔만 해준다. 📝 Type Casting과 Type Assertion의 차이점 Type casting : 데이터의 타입을 변환 ⇒ 실제 타입이 변하는 것 Type assertion : 데이터의 타입을 명시 ⇒ 데이터 타입에 영향을 안 준다. 📝 Type Assertion 사용법 // as let someValue: unknown = "this is a string… -
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
2021.11.29🎯 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator) null 병합 연산자 사용법 : A ?? B es2020에서 추가된 문법이며 좌항이 null, undefined인 경우에만 B를 리턴한다. null, undefined를 제외한 falsy 값을 그대로 리턴 하고 싶은 경우 사용한다. 기존의 A || B는 A가 falsy 한 값(0, ‘’, -0, NaN 등)인 경우 B를 반환한다. 📝 Default 값을 정의할 때 :: ||를 쓰는 경우와 ??를 쓰는 경우 📕 OR(||) 사용 // price가 0인 경우 -1 반환 function getPrice(product: { price?: number }) { return product.price || -1; } price… -
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
2021.11.29🎯 타입스크립트 옵셔널 체이닝 (Optional Chaining) 옵셔널 체이닝은 객체뿐만 아니라 배열과 함수에도 사용할 수 있다. 접근하는 객체의 프로퍼티가 null 또는 undefined일 수 있는 optional property인 경우 if 문을 사용하지 않고 넘어가게 하는 체이닝 방법이다. es2020에서 추가된 문법이며 객체가 null 또는 undefined이면 undefined를 리턴하고 그렇지 않은 경우 데이터 값을 리턴한다. 프로그래밍에서 ?는 보통 옵셔널을 뜻한다. 있을 수도 있고 없을 수도 있다. ex) data?.property 📝 &&와 ?.의 차이점은? 📕 && 사용 type Dog = { hasTail: boolean; 살랑살랑: () => string; }; /* hasTail…
댓글을 사용할 수 없습니다.