타입스크립트의 함수는 클래스나 네임스페이스 내에서 선언할 수 있고, 때론 모듈로서 사용된다.
타입스크립트는 자바스크립트와 동일한 형태로 함수를 선언하고 호출한다. 자바스크립트 함수의 형태는 기명함수와 익명함수로 나뉜다.
기명함수
function 함수명(매개변수){}
익명함수
const 함수를 담을 변수 = function(){}
자바스크립트는 느슨한 타입의 언어입니다. 함수의 매개변수의 타입이나 반환 타입은 없지만 프로그램이 실행 될 때 동적으로 타입을 할당해 추론합니다. 그러나 타입이 없기 때문에 의도치 않은 타입변환이 있을 수 있습니다. 때문에 함수 내부에서 매개변수의 타입을 검사하는 기능이 필요하게 됩니다. 타입스크립트는 매개변수나 반환값에 타입을 지정할 수 있어서 자바스크립트보다 타입 안전성이 높고 또 타입 검사가 필요없어지니 더 간결하게 코드를 짤 수 있다.
타입 스크립트의 함수는 매개변수나 반환값의 타입을 추가해 타입 안전성을 강화했다. 덕분에 함수 내부에서 매개변수의 타입을 체크할 필요없이 사용할 수있고 함수 반환값의 타입도 명확해 졌다.
function say(word:string):string{}
위와 같이 매개변수 옆에 매개변수의 타입을 )옆에 반환값을 타입을 선언해줄 수 있다.
타입스크립트는 ES6에 추가된 매개변수의 기본값을 사용할 수 있다. 매개변수의 기본값이라 함은 함수 호출 시 매개변수가 전달되지 않는 상황에서 사용하게 되는 초기값을 의미한다.
function add(a:number=0,b:number=0){return a+b};
add(5) // 매개변수 b가 전달 되지 않아 초기값인 0으로 평가
나머지 매개변수는 ES6에 제안된 특징으로 매개변수의 갯수가 정해지지 않았을 때, 그 매개변수들을 배열로 받아주는 기능이다. 갯수가 정해지지않았기 때문에 순서가 중요하지 않는 많은 요소들을 전달하는데 유용하다. 나머지 매개변수는 ...으로 선언한다.
function line(...word){}
위의 함수를 보면 모든 인수를 나머지 매개변수로 받고 있다. 몇 개의 인수를 전달하든 word변수에 배열로 전달될 것이다.
이 나머지 매개변수도 타입을 선언해 줄 수 있다. 해당 매개변수의 내용을 인지하고 있다면, 타입 선언을 해주자
function line(...word:string[]){}
나머지 매개변수는 배열이고 위 함수에서는 문자열을 요소로 같는 배열로 사용될 것이다. 때문에 string[]이라는 타입을 선언해준다.
앞서 본 나머지 매개변수는 생각한 매개변수보다 인수가 더 많이 들어올 때를 대비한 기능이다. 그렇다면 인수가 더 적게 들어올 때는? 이럴 때를 대비해서 선택매개변수가 있다. 선택 매개변수란 인수로 전달받지 않을 수도 있다는 선언을 해주는 것으로 매개변수 뒤에 ?를 붙인다.
function line(word:string,say?:string){}
선택 매개변수를 선언하면 해당 매개변수의 타입 검사를 해줘야한다.
선택 매개변수를 사용할 때 제약이 있는데 바로 초기값을 사용할 수 없음이다. 선택 매개변수를 선언하면 선택 매개변수에는 초기값을 사용할 수 없다. 또 필수 매개변수보다 뒤에 와야한다.
function line(say?:string, word:string){}
이러면 에러가 난다. 이 땐 초기값 설정을 해주면 에러를 피할 수는 있다.
function line(say?:string, word:string="hi"){}
함수 오버로드는 객체 지향의 특징을 말할 때 사용하는 오버로드와 비슷한 기능을 한다. 함수명은 같지만 매개변수와 반환타입이 다른 함수를 여러개 선언할 수 있다.
이 함수 오버로드는 컴파일 시간에 가장 적합한 오버로드를 선택하여 컴파일하기 때문에 런타임 비용이 들지 않는다. 이때 조심할 것은 결국 하나의 함수이기 때문에 각 오버로들를 독립된 블록으로 선언하면 안된다는 점이다.
function line(say?:string, word:string):string{}
function line(say?:number, word:number):number{}
function line(say?:any, word:any):any{}
함수 오버로드를 사용하는 방법은 일반적인 함수 타입을 가장 아래에 선언하고 그 위로 구체적인 타입들을 선언하는 것이다.
function line(say?:string, word:string):string
function line(say?:number, word:number):number
function line(say?:any, word:any):any
{}
익명함수를 좀더 간단하게 표현 할 수 있는 방법이 화살표 함수이다. 화살표 함수는 람다함수라고 할 수 있다.
const funq = ()=>{}
화살표 함수를 쓸 때 특징으로 매개변수가 없을 땐 ()를 쓰고 하나일 땐 생략가능, 2개 부턴 다시 써줘야한다. 함수 몸체에서 코드가 리턴문 한줄이라면 return과 코드 블럭을 생략할 수 있다.
const funq = ()=>{}
const funq = a => a
const funq = (a,b)=>a+b
화살표 함수는 무엇보다 가독성이 좋다. 때문에 filter, reduce, setTimeout등의 콜백함수가 필요한 함수안에서 많이 사용된다.
[...a].filer((item,idx)=>{});
[...a].reduce((acc,cur,idx)=>{})
화살표 함수는 객체 리터럴에서 메소드로도 사용할 수 있다. 이때 메소드 내부에서 객체의 다른 요소들을 참조하고 싶을 때 this를 사용하는데, 그냥 this를 사용하면 코드 어시스트가 동작을 안한다...이를 해결하려면 객체에 타입을 선언해줘야한다.
interface objType {
name:string,
say(this:objType,to:string):string
// this를 사용하기 위해 매개변수자리에서 this의 타입을 해당 객체타입으로 선언해주고
// 다른 매개변수나 반환값도 타입지정을 해준다.
}
let obj :objType = {
name: "백승일",
say:(this:objType,to:string)=>{}
}
this의 타입을 지정해줌으로 내부 참조시 코드 어시스트가 동작할 수 있다. 이렇게 된 이유는 this는 타입이 없기 때문이다. 그래서 인터페이스를 통해 this의 타입을 지정해준다면 문제가 해결된다. 이런 과정을 생략하는 것을 방지하려면 tsconfig에 noImplictThis옵션을 켜주면 반드시 this의 타입을 선언해줘야한다.
익명함수는 변수에 할당할 수 있습니다.
const funq = ()=>{}
이때 매개변수와 반환값의 타입지정도 가능하지요
const funq = (a:string):string=>{}
그리고 이 익명함수를 담는 변수도 타입선언이 가능합니다.
const funq :(a:string)=> string = (a:string):string=>{};
하지만 이렇게 되면 코드의 가독성이 떨어집니다. 필자는 처음에 뭐지 콜백인가 했다. 이를 막기 위해서 type 엘리어스를 이용하여 미리 타입을 분리해서 사용해준다.
type funqType = (a:string)=> string
const funq : funqType = (a:string):string=>{};
이렇게 타입을 분리해두면 재활용도 가능해진다.
type funqType = (a:string)=> string
const funq : funqType = (a:string):string=>{};
const funq2 : funqType = (a:string):string=>{};
이렇게 익명함수를 할당받는 변수에 타입을 선언하면 좋은 점은
정도가 되겠다.
콜백 함수라 함은 다른 함수의 매개변수로 전달되는 함수이다. 콜백함수를 받는 함수를 고차함수라고 하며 콜백함수를 전달 받거나 함수를 반환해주는 특성이 있다.
setTimeout(()=>{
console.log("으악!")
},1000)
이렇게 고차함수에 매개변수로 들어가는 콜백함수는 타입을 지정하지 않아서 타입 안전성이 떨어진다. 콜백함수의 역할이 중요해진다면 앞서 한 것 처럼 타입을 분리해서 추가해주는게 좋다.
type callBackType = (a:string)=>void;
const callBack:callBackType = a => a;
function sayWhat (message:string,callBack){
return callBack(message);
}
console.log(sayWhat("hi",callBack));
이처럼 콜백함수의 타입을 한번 지정해 놓으면 재사용이 가능하기 때문에 코드가 더 간결해 질 수 있다.