코딩/Typescript

타입스크립트 콜백함수 알아보기 - 타입스크립트 Typescript 강좌 3편

드리프트 2021. 10. 30. 16:00
728x170

 

 

 

 

안녕하세요?

오늘은 타입 스크립트 강좌 3편을 이어 나가도록 하겠습니다.

 

오늘 내용은 콜백 함수 관련인데요.

 

지난 시간부터 이어져 오던 환경에서 새로운 파일을 만들어 보겠습니다.

 

 

1. 콜백 함수의 타입은?

// funcs-with-funcs.ts

export function printToFile(text: string, callback): void {
    console.log(text);
    callback();
}

printToFile 함수를 만들었는데요.

 

text인자를 받아서 console.log 하고 있습니다.

 

그리고 callbak 함수를 실행하는데요.

 

callback 함수의 타입은 뭘까요? 마우스를 올려다 놓아 볼까요?

 

 

callback을 그냥 any 타입으로 추론해 버렸네요.

 

VS Code의 인텔리 센스도 어쩔 수 없나 봅니다.

 

왜냐하면 callback에 대한 정보가 하나도 없기 때문입니다.

 

그럼 callback 즉, 콜백 함수의 타입을 어떻게 부여할까요?

 

방법은 다음과 같습니다.

 

export function printToFile(text: string, callback: () => void): void {
}

 

타입 스크립트에서 콜백 함수의 타입은 애로우 함수를 이용합니다.

 

그리고 다음과 같이 콜백 함수의 인자도 명시할 수 있는데요.

 

export function printToFile(text: string, callback: (v: number) => void): void {
}

 

그럼 좀 더 어려운 예제로 넘어가 볼가요?

 

배열을 바꾸는 함수를 만들어 보겠습니다.

 

export function arrayMutate(numbers: number[], mutate: (v: number) => number): number[] {
    return numbers.map(mutate);
}

console.log(arrayMutate([1, 2, 3], (v) => v * 10));

 

arrayMutate 함수는 numbers라는 number 배열을 받고, mutate라는 콜백 함수도 받는데요.

 

mutate라는 콜백 함수의 정보는 v라는 number를 받아서 number를 리턴하는 함수입니다.

 

그리고 arrayMutate라는 함수 자체는 number []를 리턴합니다.

 

실제 코드 내용도 numbers.map 함수를 썼고 map 함수 인수에 mutate 콜백 함수를 넣었습니다.

 

그리고 마지막 줄에 보시면 arrayMutate 함수에 대한 예제 실행이 있는데요.

 

numbers는 [1,2,3] 이 되고, map함수의 인수로 mutate 함수는 v = > v*10 이 전달되었습니다.

 

실행 결과도 예상한 데로 나왔습니다.

 

넘겨주는 배열도 [1, 20, 3]으로 변경했어도 실행 결과는 잘 나왔네요.

 

 

 

2. 함수 타입 정의하기

 

여기서 한 가지 마음에 걸리는 게 있는데요.

 

바로 mutate라는 콜백 함수의 타입이 너무 길고 번거롭다는 점입니다.

 

그래서 타입 스크립트에서 제공해주는 다른 방법이 있죠.

 

바로 type 키워드인데요.

 

예제를 보시죠.

 

먼저, 콜백 함수의 타입은  (v: number) => number입니다.

 

그래서 다음과 같이 콜백 함수의 타입을 미리 정의할 수 있죠.

 

export type MutateFunction = (v: number) => number;

export function arrayMutate(
    numbers: number[],
    mutate: MutateFunction
): number[] {
    return numbers.map(mutate);
}

console.log(arrayMutate([1, 20, 3], (v) => v * 10));

 

type 키워드는 interface 키워드랑은 다르게 "="로 명명합니다.

 

그리고 type 자체를 export 할 수도 있습니다.

 

우리가 MutateFunction 타입을 정의했고, 그 새로운 타입을 바로 밑에 arrayMutate 함수의 인자인 콜백 함수의 타입으로 썼습니다.

 

이렇게 type을 이용하니까 좀 더 간단하게 보이죠?

 

실행해볼까요?

 

실행 결과는 똑같습니다.

 

 

이제 MutateFunction이라는 타입을 이용해서 다른 함수를 만들어 볼까요?

 

const myNewMutateFunc: MutateFunction = (v: string) => `${v * 10}`;

 

VS Code의 인텔리 센스가 에러를 나타내 주고 있습니다.

 

무슨 에러일까요?

 

 

myNewMuatateFunc 함수의 타입이 MutateFunction인데 MutateFunction 타입은 숫자를 받아 숫자를 리턴하는 타입인데, 위 코드에서는 string을 받아서 string을 리턴한다고 불평하고 있네요.

 

맞습니다. 이렇듯 우리가 MutateFunction이라는 타입을 만들어 놓으면 타입 스크립트는 알아서 에러 체크해주고 있죠.

 

우리가 타입을 매번 만드는 게 귀찮을 뿐이지 사실 이렇게 해두면 자바스크립트를 매우 안전하게 쓸 수 있지 않을까요?

 

이제 에러를 고쳐 볼까요?

 

const myNewMutateFunc: MutateFunction = (v: number) => v * 10;

 

위 그림처럼 VS Code의 인텔리 센스가 에러를 나타내지 않고 있습니다.

 

 

 

3. 함수 리턴하기

 

함수를 리턴할 때는 타입 스크립트에서 어떻게 해야 할까요?

 

자바스크립트 클로저 예제를 들어서 설명해 보겠습니다.

 

export function createAdder(num: number) {
    return (val: number) => num + val;
}

const addOne = createAdder(1);
console.log(addOne(55));

 

createAdder라는 함수는 함수를 리턴하고 있는데요.

 

그래서 밑에 보면 addOne이란 함수는 createAdder(1)이라고 1을 더해주는 함수를 리턴합니다.

 

그래서 실행 결과를 보면 다음과 같습니다.

 

 

56으로 잘 나왔네요.

 

그럼 createAdder 함수의 리턴 타입 명기가 없었는데요. 마우스를 잠시 올려 볼까요?

 

리턴 타입이 (val: number) => number라고 나오네요.

 

이제 우리의 createAdder 함수의 완전한 원형은 다음과 같습니다.

export function createAdder(num: number): (val: number) => number {
    return (val: number) => num + val;
}

그럼 createAdder 함수의 리턴 타입도 type 키워드로 만들어 볼까요?

 

export type AdderFunction = (val: number) => number;

export function createAdder(num: number): AdderFunction {
    return (val: number) => num + val;
}

const addOne = createAdder(1);
console.log(addOne(55));

 

AdderFunction이란 타입을 새로 만들었습니다.

 

다시 실행해 볼까요?

 

 

역시나 잘 되고 있습니다.

 

type라는 키워드는 우리가 앞으로 타입 스크립트로 코드를 작성할 때 아주 유용하게 쓸 수 있는 도구이고요.

 

특히 제네릭을 할 때 아주 유용하게 쓸 수 있습니다.

 

오늘은 type의 맛보기라고 생각하시면 되겠습니다.

 

그럼. 다음 시간에는 타입 스크립트의 Function Overloading에 대해 알아보겠습니다.

 

 

그리드형