💡 함수 오버로딩
합수의 오버로딩이란 하나의 함수를 매개변수의 개수나 타입에 따라 다르게 동작하도록 만드는 문법입니다. 하나의 함수명을 func이고 모든 매개변수의 타입을 number라고 가정합니다. 저는 2가지 버전의 함수를 만들어보려고 합니다.
⓵ 매개변수가 1개일 때 매개변수에 20을 곱한 값을 출력하는 함수
⓶ 매개변수가 3개일 때 모든 매개변수를 더한 값을 출력하는 함수
function func(a: number): void;
function func(a: number, b: number, c: number): void;
타입스크립트에서 함수 오버로딩을 구현하기 위해서는 먼저 다음과 같이 버전별 오버로드 시그니쳐를 만들어 주어야 합니다. 이렇게 구현부 없이 선언부만 만들어둔 함수를 오버로드 시그니쳐라고 합니다. 위 코드에서 보다시피 func 함수는 매개변수 1개를 받는 버전과 매개변수를 3개를 받는 총 2개의 버전이 있음을 안내하고 있습니다. 오버로드 시그니쳐를 만들었다면 실제로 함수가 어떻게 실행될 것인지를 정의하는 부분인 구현 시그니쳐를 만들어주어야 합니다.
function func(a: number): void;
function func(a: number, b: number, c: number): void;
// 실제 구현부: 구현 시그니처
function func(a: number, b?: number, c?: number) {
if (typeof b === "number" && typeof c === "number") {
console.log(a + b + c);
} else {
console.log(a * 20);
}
}
func(); // ❌
func(1);
func(1, 2); // ❌
func(1, 2, 3);
구현 시그니쳐의 매개변수 타입은 모든 오버로드 시그니쳐와 호환되도록 만들어야 합니다. 따라서 위 코드에서는 매개변수 b와 c를 선택적 매개변수(?)로 만들어서 매개변수를 하나만 받는 첫번째 오버로드 시그니쳐와도 호환되도록 만들어주었습니다. 우리는 매개변수를 1개 또는 3개를 받는 func함수를 만들었는데 호출 시 위 코드에서 보다시피 매개변수를 0개 또는 2개 받아주면 오류가 발생하게 됩니다.
💡 사용자 정의 타입가드
사용자 정의 타입가드란 참 또는 거짓을 반환하는 함수를 이용하여 우리 마음대로 타입 가드를 만들 수 있도록 도와주는 타입스크립트 문법입니다.
// 사용자 정의 타입가드
type Dog = {
name: string;
isBark: boolean;
};
type Cat = {
name: string;
isScratch: boolean;
};
type Animal = Dog | Cat;
function warning(animal: Animal) {
if ("isBark" in animal) {
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else if ("isScratch" in animal) {
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
Dog와 Cat이라는 2개의 타입을 정의하고 두 타입의 유니온 타입인 Animal 타입을 정의하였습니다. 다음으로는 매개변수로 Animal 타입의 값을 받아 동물에 따라 각각 다른 경고를 콘솔에 출력하는 함수 warning을 만들었습니다. 만ㄴ약 이 함수를 호출하고 인수로 Dog 타입의 객체를 전달하면 "짖습니다" 또는 "안짖어요"를 출력할 것이고, Cat 타입의 객체를 전달하면 "햘큅니다" 또는 "안햘퀴어요"를 출력할 것입니다.
그런데 in 연산자를 통해 타입을 좁히는 방식은 직관적이지 않기 때문에 비추천한다고 이전에 살펴보았습니다. 예를 들어 만약 Dog 타입의 프로퍼티명이 수정되거나 추가 또는 삭제되는 경우에는 타입 가드가 제대로 동작하지 않을 수도 있기 때문입니다.
// Dog 타입인지 확인하는 타입 가드
function isDog(animal: Animal): animal is Dog {
return (animal as Dog).isBark !== undefined;
}
// Cat 타입인지 확인하는 타입 가드
function isCat(animal: Animal): animal is Cat {
return (animal as Cat).isScratch !== undefined;
}
function warning(animal: Animal) {
if (isDog(animal)) {
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else if ("isScratch" in animal) {
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
isDog 함수는 매개변수로 받은 값이 Dog 타입이라면 true, 아니라면 false를 반환합니다. 이때 반환값의 타입으로 animal is Dog를 정의하면 이 함수가 true를 반환하면 조건문 내부에서는 이 값이 Dog 타입임을 보장하는 것입니다. 따라서 warning 함수에서 isDog 함수를 호출하여 매개변수의 값이 Dog 타입인지를 확인하여 타입 좁히기가 가능합니다.
출처) 한 입 크기로 잘라먹는 타입스크립트(TypeScript)_이정환
'📍 프로그래밍 언어 > TypeScript' 카테고리의 다른 글
[ TypeScript ] 클래스 이해하기: JavaScript 차이점, 인터페이스, 그리고 접근 제어자 (0) | 2024.12.22 |
---|---|
[ TypeScript ] 인터페이스의 활용: 기본 개념부터 확장과 선언 합치기 (0) | 2024.12.21 |
[ TypeScript ] 함수 타입: 정의와 표현식, 호출 시그니처, 타입 호환성 (1) | 2024.12.19 |
[ TypeScript ] 타입 단언과 타입 좁히기 활용법, 서로소 유니온 타입의 이해 (0) | 2024.12.19 |
[ TypeScript ] 대수 타입 & 타입 추론: 강력한 타입 시스템 이해하기 (0) | 2024.12.19 |