[TypeScript] 함수 오버로딩의 개념과 주의사항 가이드
type Combinable = string | number;
function add1(a: Combinable, b: Combinable) {
// return a + b; // 타입 추론이 안되는 경우 타입 어노테이션을 사용해야 함
// 타입가드 : typeof type 의 교차 타입인 경우
if (typeof a === "string" || typeof b === "string") {
return a.toString() + b.toString();
}
return a + b;
}
const result = add1("type", "script");
result.split(" ");
위 코드에서 const ressult = add1("type", "script"); 로 사용하면 split 에서 아래와 같은 오류가 발생하게 됩니다.
Property 'split' does not exist on type 'string | number'.
Property 'split' does not exist on type 'number'.ts(2339)
반환값이 정확히 어떤 게 나올지 모르기 때문에 number 가 반환이 되면 string 메서드인
split 를 사용할 수 없기 때문입니다.
그래서 아래처럼 as string 을 추가하여 형변환을 시켜줘야 오류를 막을 수 있습니다.
const result = add1("type", "script") as string;
result.split(" ");
하지만 이후 다른 개발자가 add1 이란 메서드를 사용하게 됬다면 형변환을 시켜야 한다는 사실을 알기 전까지
리소스 손실이 될 수 밖에 없습니다.
그래서 처음 함수를 선언할 때부터, 함수의 파라미터와 리턴 타입을 적어주어
따로 형변환을 추가하지 않아도 함수 오버로딩을 시키면 이러한 혼란을 막을 수 있습니다.
그리고 아래 같은 장점들도 있습니다
1.타입 안정성 향상
2.형변환(as) 불필요
3. 코드 가독성 개선
4.IDE 자동완성 지원 강화
type Combinable = string | number;
// 오버로드 시그니처들
function add1(a: number, b: number): number;
function add1(a: string, b: string): string;
function add1(a: string, b: number): string;
function add1(a: number, b: string): string;
// 구현 시그니처 함수
function add1(a: Combinable, b: Combinable) {
// return a + b; // 타입 추론이 안되는 경우 타입 어노테이션을 사용해야 함
// 타입가드 : typeof type 의 교차 타입인 경우
if (typeof a === "string" || typeof b === "string") {
return a.toString() + b.toString();
}
return a + b;
}
const result = add1("type", "script");
result.split(" ");
위와 같은 오버로딩시 주의점은 다음과 같습니다.
1. 함수명이 같아야 하며, 직관적으로 알기 쉽게 구현 함수 바로 상단에 적어주는 게 좋습니다.
2. 구현 함수의 파라미터와 타입이 시그니처의 파라미터 타입을 포함해야 합니다
예제의 string , number 이외의 타입이 나오면 안됩니다
그리고 오버로드 시그니처는 파라미터수가 더 적어도 상관없습니다.
function add1(a: number): number;
3. 타입는 가드 필수 입니다
4. 더 구체적인 시그니처를 먼저 선언해야합니다
5. 각 오버로드 시그니처에는 명확한 반환 타입을 지정해야 합니다