이번 포스팅에서는 타입스크립트 함수 타입정의에 대해 알아보게겠습니다.
함수 정의하기
const func = (매개변수:타입, 매개변수: 타입) : 리턴타입 =>{
//타입스크립트 함수 기본 정의입니다.
}
옵셔널 매개변수
const func = (매개변수:타입, 매개변수?: 타입) : 리턴타입 =>{
//? 기호가 들어간 매개변수는 옵셔널 매개변수가 됩니다.
}
매개변수에 디폴트 값 지정
const func = (매개변수 = 디폴트값) : 리턴타입 =>{
//매개변수에 디폴트 값을 지정해줍니다.
}
여러타입을 가지는 매개변수
const func = (매개변수:타입|타입) : 리턴타입 =>{
//매개변수의 타입을 두가지로 지정해주었습니다.
}
매개변수를 동적으로 받기
const func = (...매개변수:Array<number>) : 리턴타입 =>{
//... 연산자를 사용하면 반드시 타입은 배열이어야 합니다.
}
this의 타입 정의하기
interface User{
name:string;
}
const user:User = {
name:'kth',
}
const func = (this:타입, 매개변수:타입) : 리턴타입 =>{
//this의 타입은 매개변수중 가장 앞에 정의해야합니다.
console.log(this.name)
}
const funcThisBinding = func.bind(user);
funcThisBinding();
함수 오버로드
함수 오버로는 같은 함수명을 가진 함수를 매개변수의 타입이나 갯수에따라 여러번 선언하는것을 말합니다.
함수 오버로드를 사용하는 상황은 아래와같습니다.
함수 오버로드를 선언할 때는 여러 개의 함수를 선언하고, 구현은 단 하나만 제공합니다.
예시
나이를 받는 매개변수 age 에 문자열, 숫자 두 타입 모두 허용하였습니다.
interface User {
name: string;
age: number;
}
function join(name: string, age: number | string): User | string {
if (typeof age === "number") {
return {
name,
age,
};
} else {
return "나이는 숫자로 입력하세요";
}
}
//Error : string | User' 형식은 'User' 형식에 할당할 수 없습니다. 'string' 형식은 'User' 형식에 할당할 수 없습니다.
const kth1: User = join("김태형", 31);
//반환 기댓값 : User 객체
//Error : 'string | User' 형식은 'string' 형식에 할당할 수 없습니다. 'User' 형식은 'string' 형식에 할당할 수 없습니다.
const kth2: string = join("김태훈", '33');
//반환 기댓값 : '나이는 숫자로 입력하세요'
실제로 코드에 이상이 없어보입니다. 하지만 타입스크립트는 에러를 표시합니다.
에러 내용을 보면, 반환되는 타입이 string | User 로 판단되는 것을 볼 수 있습니다.
해답
함수 오버로딩을 통해 유동적인 타입별, 리턴타입을 확실히 정해줍니다.
interface User {
name: string;
age: number;
}
//각 타입별 함수 오버로딩
function join(name: string, age:number):User
function join(name: string, age:string):string
function join(name: string, age: number | string): User | string {
if (typeof age === "number") {
return {
name,
age,
};
} else {
return "나이는 숫자로 입력하세요";
}
}
const kth1: User = join("김태형", 31);
const kth2: string = join("김태훈", '33');
이렇게 매개변수의 타입, 반환값의 타입이 유동적이라면 함수 오버로딩을 통해 해결할 수 있습니다.
잘못된 사용 방식과 단점
과도한 오버로드 사용: 함수가 너무 많은 오버로드를 가질 경우, 코드의 복잡도가 증가하고 유지보수가 어려워질 수 있습니다.
오버로드와 구현 간의 불일치: 모든 오버로드 시그니처가 구현 부분과 일치하지 않으면 오류가 발생할 수 있습니다. 즉, 각 오버로드에 대한 적절한 처리가 구현 부분에 반영되어야 합니다.
타입 안정성 저하: 오버로드 시 any 타입을 과도하게 사용하면, 타입스크립트의 주요 장점 중 하나인 타입 안정성이 저하될 수 있습니다.any 타입뿐 아니라 다양한 타입을 허용하게되면 안정성이 떨어질 수 밖에 없습니다.
가독성 저하: 많은 오버로드는 코드를 읽고 이해하기 어렵게 만들 수 있습니다. 특히 오버로드가 많은 경우, 어떤 시그니처가 호출되는지 파악하기 어려울 수 있습니다.
사용 시 고려할 점
오버로드는 필요한 경우에만 제한적으로 사용해야 합니다.
가능하다면, 유니언 타입(Union Types)을 사용하여 오버로드를 단순화하는 것이 좋습니다.
any 대신 구체적인 타입을 사용하여 타입 안정성을 유지해야 합니다.
함수 오버로드는 타입스크립트에서 강력한 기능을 제공하지만, 남용되면 코드의 복잡성과 유지보수성이 저하될 수 있습니다. 따라서 오버로드는 신중하게 사용되어야 합니다.