TypeScript

[TypeScript] 함수 오버로딩의 개념과 주의사항 가이드

머지?는 병합입니다 2024. 12. 21. 23:26
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. 각 오버로드 시그니처에는 명확한 반환 타입을 지정해야 합니다