반응형
250x250
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

오버로딩(any를 써야하는 경우!) 본문

TS/TS(with ZeroCho)

오버로딩(any를 써야하는 경우!)

5_hyun 2023. 9. 28. 13:02

오버로딩 사용이 필요한 경우

오버로딩은 호출할 수 있는 함수의 타입을 미리 여러 개 타이핑하는 기법이다.

function add(x: string | number, y: string | number): string | number {
	return x + y;
}
add(1, 2);
add('1', '2');
add('1', 2);
add(1, '2');

x와 y가 같은 타입일 경우에만 함수를 실행시키고 싶었다면, 이 코드에서는 불가능하다. 서로 다른 타입이어도 코드가 동작할 수 있도록 구현되어 있다. 그렇기에 이런 경우에 오버로딩 기법을 사용할 수 있다.

오버로딩 예시

function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
  return x + y;
}

add(1, 2); // 3
add("1", "2"); // 12
add(1, "2"); // error
add("1", 2); // error

위 코드를 보면 처음 2줄은 함수의 구현부(implementation)가 없다. 그리고 마지막 선언은 구현부가 있지만 매개변수 타입이 any이다.

any를 사용하지 않으면 implicitAny 에러가 발생하게 된다.

=> 이것이 매개변수 타입을 any로 만드는 것이 아니고 위 2줄에서 선언한 타입 조합만 가능하게 한다.

 

-오버로딩 순서

오버로딩을 선언하는 순서도 타입 추론에 영향을 끼친다. 

만약 여러 오버로딩에 동시해 해당하면 제일 먼저 선언된 오버로딩에 해당한다.

 

function example(param: string): string;
function example(param: string | null): number;
function example(param: string | null): string | number {
  if (param) {
    return "string";
  } else {
    return 123;
  }
}

const result = example("what"); // string

먼저 이 코드에서는 result의 타입이 string으로 추론이된다.

 

function example(param: string | null): number;
function example(param: string): string;
function example(param: string | null): string | number {
  if (param) {
    return "string";
  } else {
    return 123;
  }
}

const result = example("what");

이렇게 순서를 바꾸면 result의 타입이 number로 추론이 된다.

 

=> 오버로딩의 순서는 좁은 타입부터 넓은 타입순으로 오게 해야 문제가 없다!

인터페이스 오버로딩

interface Add {
  (x: number, y: number): number;
  (x: string, y: string): string;
}

const add: Add = (x: any, y: any) => x + y;

add(1, 2); // 3
add("1", "2"); // 12
add("1", 2); // error
add(1, "2"); // error

이런 식으로 코드를 구현하면 인터페이스도 오버로딩을 할 수 있다.

타입 별칭 오버로딩

type Add1 = (x: number, y: number) => number;
type Add2 = (x: string, y: string) => string;
type Add = Add1 & Add2;
const add: Add = (x: any, y: any) => x + y;

add(1, 2); // 3
add("1", "2"); // 12
add("1", 2); // error
add(1, "2"); // error

타입 별칭은 & 연산자를 사용해서 오버로딩을 할 수 있다.

오버로딩을 남용하지 말자

오버로딩을 하지 않아도 되는 상황에서 오버로딩을 하면 문제가 발생할 수 있다.

 

-문제점 1

function a(param: string): void;
function a(param: number): void;
function a(param: string | number): void {}

function errorA(param: string | number) {
  a(param);
}

이 경우에는 param이 string | number인데 맨 처음 선언에 만족해서 마지막 선언인 매개변수 string | number에 가지 못하고 첫 번째, 두 번째 오버로딩에서 에러가 난다.

 

-문제점 2

function b(p1: string): void;
function b(p1: string, p2: number): void;
function b(p1: string, p2?: number) {}

function errorB(p1: string, p2: number | undefined) {
  b(p1, p2);
}

이 경우에는 p2가 없어서 에러가 나거나, p2가 number | undefined인데 number라서 에러가 발생한다.

 

-오버로딩을 제거한 코드

function a(param: string | number): void {}

function errorA(param: string | number) {
  a(param);
}

function b(p1: string, p2?: number) {}

function errorB(p1: string, p2: number | undefined) {
  b(p1, p2);
}

이렇게 오버로딩을 제거하면 에러가 사라진다.

 

유니언이나 옵셔널 매개변수를 활용하는 경우에는 오버로딩을 사용하지 않는 것이 좋다!

728x90
반응형

'TS > TS(with ZeroCho)' 카테고리의 다른 글

infer로 타입 추론(with 컨디셔널 타입)  (0) 2023.11.11
공변성과 반공변성(함수)  (1) 2023.10.02
타입을 집합으로 생각하자  (0) 2023.09.15
React with TS  (0) 2022.09.12
Axios 만들어보기  (0) 2022.09.07
Comments