함수의 기본적인 타입 선언
- 매개변수와 반환값에 타입을 지정하였습니다.
- 반환 값에 타입을 정하지 않을 때는
void
라도 사용하는 것이 좋습니다.
함수 표현식
function sum1(a: number, b: number): number {
return a + b;
}
함수 선언식
//* 함수 선언식
let sum2 = function (a: number, b: number): number {
return a + b;
};
화살표 함수
//* 함수 선언식
let sum3 = (a: number, b: number): number => {
return a + b;
};
Call Signature(함수 타입)
타입스크립트에서는 함수를 표현하는 타입을 미리 선언하는것이 가능하다.
위의 함수 표현식에서는 함수 리턴 타입을 콜론(:)으로 표현했지만, 함수 타입을 선언할 때는 화살표로 리턴 타입을 표현하니 헷갈릴 수 있다.
let sum4: (arg1: number, arg2: number) => number; // 변수에 미리 함수 타입을 지정
sum4 = function (a, b) { // 미리 변수에 함수 타입을 지정해놓았으므로 타입을 쓰지않아도 된다.
return a + b;
};
매개 변수 표현
타입 스크립트에서는 함수의 인자를 모두 필수 값으로 간주한다.
그러므로, 매개변수에 넘겨야 할 값이 없을 때는, undefined
나 null
같은 값이라도 인자로 넘겨주어야 하며, 컴파일러에서는 정의된 매개변수 값이 넘어 왓는지 확인한다.
function sum(a: number, b: number): number {
return a + b;
}
sum(10, 20); // 30
sum(10); // 인자 없음 에러
선택적 매개 변수 표현
정의된 매개변수의 갯수 만큼 인자를 넘기지 않아도 되게 만들고 싶다면, 물음표(?)를 이용해서 정의할 수 있다.
function sum(a: number, b?: number): number {
return a + b;
}
하지만 해당 코드에서는 b의 인자를 주지 않을 경우 undefined로 할당되기 때문에, a + b연산을 수행하면서 오류가 날 수 있다.
그러므로 Null 병합 연산자(??) 를 사용하여 null 또는 undefined인 경우 0을 반환하도록 지정하는 식으로 처리 가능하다.
function sum(a: number, b?: number, c?: number): number {
return a + (b ?? 0) + (c ?? 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2)); // 3
console.log(sum(1)); // 1
하지만 선택적 매개변수를 사용할 때 주의점은 선택적 매개변수가 이외의 함수 인자 앞으로 위치하면 안된다.
매개변수 초기화(init)
ES6 문법과 마찬가지로 매개변수에 기본값을 할당하면 타입 추론을 통해서 알맞은 인자를 넣어준다.
function sum(a: number, b = 100): number { // 타입 추론을 통해 인자타입을 선언하지 않아도 된다.
return a + b;
}
console.log(sum(10, undefined)); // 110
console.log(sum(10)); // 110
console.log(sum(10, 10)) // 20
나머지 매개변수
ES6에서 사용되는 스프레드 매개변수 역시 타입지정을 통해서 사용 가능하다.
function sum(a: number, ...nums: number[]): number {
let totalOfNums = 0;
for (let key in nums) {
totalOfNums += nums[key];
}
return a + totalOfNums;
}
네임드 파라미터
네임드 파라미터는 함수 아규먼트 부분 전체를 객체로 감싸주고, 그 뒤에 타입을 정의하는 방식이다.
function getInfo({ name, age = 15, language }: { name: string; age?: number; language?: string }): string {
const nameText = name.substr(0, 10);
const ageText = age >= 35 ? 'senior' : 'junior';
return `name: ${nameText}, age: ${ageText}, language: ${language}`;
}
console.log(getInfo({ name: '홍길동', age: 11, language: 'kor' }));
console.log(getInfo({ name: '홍길동' }));
타입스크립트의 this 표현
명시적 this
다음의 예시에서 carFn
메소드는 전역 렉시컬 스코프에 위치하므로 해당 function안에서 this를 찾게 되므로 this에 any 오류가 일어나게 된다.
interface Car {
speed: number;
}
const car: Car = {
speed: 300
}
function carFn(introduce: string) {
console.log(`${introduce} ${this.speed}`); //해당 this에는 형식 주석이 없으므로 암시적 'any' 형식이 포함된다.
}
carFn.call(car)
이 경우에 this의 타입을 명시적으로 선언하여 오류를 없앨수 있다. 첫번째 매개변수로 this를 선언하면 된다.
interface Car {
speed: number;
}
const car: Car = {
speed: 300
}
function carFn(this: Car, introduce: string) {
console.log(`${introduce} ${this.speed}`); //해당 this에는 형식 주석이 없으므로 암시적 'any' 형식이 포함된다.
}
carFn.call(car, 'This car speed is'); // This car speed is 300
타입스크립트의 함수 오버로딩
타입 스크립트에서의 함수 오버로드 선언은 중괄호 { } 없는 함수를 실제 함수 위에다가 써주면 된다.
function sum(a: string, b: string): string; // 오버로드 함수 선언
function sum(a: number, b: number): number; // 오버로드 함수 선언
function sum(a: any, b: any): any { // 오버로드 함수 실행부 (any를 써준다)
return a + b;
}
add('hello ', 'world~'); // hello world
add(1, 2); // 3
💡 타입크립트에서는 any 사용을 하지 말라고 했는데, 오버로드 함수에는 써도 될까?결론부터 말하면 ‘사용해도 된다’ 이다.
컴파일러는 오버로드 함수 선언부의 타입들만 보고 함수를 판단하기 때문에 실행부에 any를 쓴다고 문제가 되지 않는다.
sum([1, 2], 3) 과 같이 오버로드 함수의 인수 타입에 정의되지 않은 데이터를 넣을 경우 컴파일러 에러가 나타나기 때문에 오버로드 함수에서의 any 표현은 타입스크립트에서 허용된다.
참고
https://inpa.tistory.com/entry/TS-📘-타입스크립트에서-함수-문법-다루기-💯-총정리
https://www.inflearn.com/course/아이오닉-ionic2-타입스크립트