Item 12 함수 표현식에 타입 적용하기
Use Function Expressions
함수를 정의하는 방법은 대표적으로 문장(statement) 또는 표현식(expression)이 있다.
function rollDice1(sides: number): number { /* ... */ } // 문장
const rollDice2 = function(sides: number): number { /* ... */ } // 표현식
const rollDice3 = (sides: number): number => { /* ... */ } // 표현식
타입스크립트에서는 함수 표현식을 사용하는 것이 좋다(고 한다). 함수의 매개변수부터 반환값까지 전체를 함수 타입으로 선언하여 함수 표현식에 재사용할 수 있기 때문이다. 따라서 불필요한 코드의 반복을 줄인다.
type DiceRollFn = (sides: number) => number
const rollDice: DiceRollFn = sides => { /* ... */ }
function add(a: number, b: number) { return a + b }
function sub(a: number, b: number) { return a - b }
function mul(a: number, b: number) { return a * b }
function div(a: number, b: number) { return a / b }
v.s.
type BinaryFn = (a: number, b: number) => number
const add = (a, b) => a + b
const sub = (a, b) => a - b
const mul = (a, b) => a * b
const div = (a, b) => a / b
아래가 더 깔끔해보인다.
fetch
함수를 예로 들어보자.
declare function fetch(
input: RequestInfo, ini?: RequestInit
): Promise<Response>
아래의 함수를 작성할 수 있다.
async function checkedFetch(input: RequestInfo, init?: RequestInit) {
const response = await fetch(input, init)
if (!response.ok) {
throw new Error('Request failed: ' + response.status)
}
return response
}
이 코드도 잘 동작하지만, 아래처럼 더 간결하게 작성할 수 있다.
const checkedFetch: typeof fetch = (input, init) => {
const response = await fetch(input, init)
if (!response.ok) {
throw new Error('Request failed: ' + response.status)
}
return response
}
이렇게 하면
input
,init
의 타입을 추론해서 생략할 수 있다.또한, throw 대신 return을 실수로 적었다면, 그 실수도 잡을 수 있다.
Summary
매개변수나 반환 값에 타입을 명시하기보다는, 함수 표현식 전체에 타입 구문을 적용하는 것이 좋다.
만약 같은 타입 시그니처를 반복적으로 작성한 코드가 있다면 함수 타입을 분리해 내거나 이미 존재하는 타입을 찾아보도록 한다. 라이브러리를 직접 만든다면 공통 콜백에 타입을 제공해야 한다.
다른 함수의 시그니처를 참조하려면
typeof fn
을 사용하자.
Last updated
Was this helpful?