일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Cypress
- Promise
- map
- 리터럴 타입
- React
- 호이스팅
- ESlint
- Jest
- 반공변성
- autosize
- recoil
- app router
- 무한 스크롤
- 인터섹션
- 결정 알고리즘
- webpack
- 타입 좁히기
- RTK Query
- CORS
- 공변성
- TS
- 태그된 유니온
- tailwind
- async/await
- SSR
- CI/CD
- useAppDispatch
- dfs
- 이분 검색
- 투포인터
- Today
- Total
짧은코딩
오버로딩(any를 써야하는 경우!) 본문
오버로딩 사용이 필요한 경우
오버로딩은 호출할 수 있는 함수의 타입을 미리 여러 개 타이핑하는 기법이다.
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);
}
이렇게 오버로딩을 제거하면 에러가 사라진다.
유니언이나 옵셔널 매개변수를 활용하는 경우에는 오버로딩을 사용하지 않는 것이 좋다!
'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 |