함수와 함수 타입

정민교·2023년 10월 29일
0

typescript

목록 보기
9/17

📒함수 타입

자바스크립트의 함수를 다른 사람에게 설명할 때 가장 좋은 방법은 어떤 매개변수를 받고 어떤 값을 반환하는지를 설명하는 것입니다.

타입스크립트도 마찬가지입니다. 이 때 매개변수와 반환값에 타입을 추가해주면 됩니다.

즉, 어떤 타입의 매개변수를 받고, 어떤 타입의 값을 반환하는지를 설명합니다.

✔️함수 타입 정의하기

📌함수 선언문 타입 정의

function func(a: number, b: number): number {
  return a + b;
}

함수의 매개변수에 타입 주석을 달고 그 뒤에 어떤 타입의 반환값이 오는 지 타입 주석을 달면 됩니다.

반환값 타입은 반환값을 기준으로 추론되기 때문에 생략도 가능합니다.

function func(a: number, b: number) {
  return a + b;
}

📌화살표 함수 타입 정의

const add = (a: number, b: number): number => a + b;

화살표 함수 타입 정의 방식도 함수 선언문 타입 정의 방식과 동일합니다.

마찬가지로 반환값 타입은 생략이 가능합니다.

const add = (a: number, b: number) => a + b;

📌함수 타입 표현식

함수 타입 표현식으로 함수 타입을 정의할 수 있습니다.

이 때는 약간 형태가 다르니 주의해서 사용해야 합니다.

// 타입 별칭과 함께 사용
type Add = (a:number, b:number) => number;
// 타입 주석에 함수 타입 표현식 사용
const add = (a:number, b:number) => number = (a, b) => a+b;

화살표 함수나 함수 선언문에서는 매개변수 부분 뒤에 반환값 타입을 명시했지만 함수 타입 표현식에선 화살표 뒤에 반환값 타입을 명시합니다.

✔️매개변수 기본값 설정하기

매개변수 선언 시 초기화를 통해 기본값을 할당할 수 있습니다.

function introduce(name = "정민교") {
	console.log(`name : ${name}`);
}

이 때는 매개변수의 타입 주석을 생략할 수 있습니다. 기본값을 기준으로 추론되기 때문입니다.

하지만 기본값과 다른 타입으로 타입 주석 작성 시 에러가 발생합니다.

함수 매개변수를 기본값으로 설정하면 자동으로 옵셔널 매개변수가 됩니다.

✔️선택적 매개변수 설정하기

매개변서 순언시 뒤에 물음표를 붙여주면 선택적 매개변수로 설정할 수 있습니다. 선택적 매개변수는 필수 매개변수 앞에 올 수 없으며 반드시 맨 뒤에 위치해야 합니다.

function introduce(name = "정민교", tall?: number) {
  console.log(`name : ${name}`);
  console.log(`tall : ${tall}`);
}

introduce("정민교", 170);

introduce("정민교");

선택적 매개변수는 자동으로 undefined 와 union된 타입으로 추론됩니다.

따라서 선택적 매개변수에 명시한 타입의 값이 올 거라고 기대하고 사용하기 위해서는 타입 좁히기가 필요합니다.

function introduce(name = "정민교", tall?: number) {
  console.log(`name : ${name}`);
  if (typeof tall === 'number') {
    console.log(`tall === ${tall}`);
  }
}

✔️나머지 매개변수(rest parameter)

나머지 매개변수(rest parameter)는 인수 목록을 배열로 전달받는 매개변수입니다. 나머지 매개변수는 반드시 맨 마지막에 위치해야 합니다.

function getSum(...rest: number[]) {
  let sum = 0;
  rest.forEach((it) => (sum += it));
  return sum;
}

number 타입의 인수들을 배열로 전달받는 getSum 함수입니다.

rest parameter를 튜플 타입으로 선언해도 됩니다.

function getSum(...rest: [number, number, number]) {
  let sum = 0;
  rest.forEach((it) => (sum += it));
  return sum;
}

이렇게 하면 getSum 함수의 타입과 매개변수 이름은 다음과 같습니다.

매개변수 이름이 임의로 정해지는 것이 싫다면 각 자리에 이름을 붙이면 됩니다.

function getSum(...rest: [a: number, b: number, c: number]) {
  let sum = 0;
  rest.forEach((it) => (sum += it));
  return sum;
}

✔️매개변수에 구조분해 할당 적용하기

매개변수에 구조분해 할당을 적용하기 위해 다음과 같이 작성하였습니다

function destructuring({prop: { nested: string }}) {

}

destructuring({prop: { nested: 'hi' }});

하지만 위 코드는 다음과 같은 에러가 발생합니다.

위 코드는 nested 속성을 string 타입으로 타이핑 한 것이 아니고 nested 속성의 값을 string 이라는 변수에 할당한 것입니다.

따라서 제대로 작성하기 위해서는 다음과 같이 작성합니다.

function destructuring({prop: {nested}}: {prop: {nested: string}}) {
  console.log(nested);
}

destructuring({prop: {nested: 'hi'}});

✔️함수를 생성자로 사용 불가

기본적으로 자바스크립트에서는 함수를 생성자로 사용할 수 있습니다. new 키워드를 붙여서 인스턴스를 생성할 수 있습니다.

하지만 타입스크립트에서는 기본적으로 함수를 생성자로 사용할 수 없고 class를 사용해야 합니다.

✔️인수로 전달하는 콜백함수의 매개변수는 생략 가능(문맥적 추론, Contextual Typing)

함수가 콜백 함수로 사용될 때 발생하는 자바스크립트의 특징입니다.

function example(callback: (error: Error, result: string) => void) {}
example((e,r) => {});
example(() => {});
example(() => true);

기본적으로 함수에는 매개변수에는 반드시 타입 주석을 작성해야 한다고 했습니다.

하지만 (e,r) => {} 과 같이 인수로 전달한 콜백함수를 보면 타입을 표기하지 않았습니다.

이처럼 인수로 전달하는 콜백 함수의 매개변수에는 타입을 표기하지 않아도 됩니다.

example 함수를 선언할 때 callback 매개변수에 타입 주석을 작성하였기 때문에 (e,r) => {} 함수는 callback 매개변수 타입으로 추론됩니다.

따라서 콜백 함수의 매개변수 eError, rstring 타입이 됩니다. 이런 현상을 문맥적 추론이라고 합니다.

콜백 함수의 매개변수를 함수를 호출할 때 사용하지 않아도 됩니다.

두 번째 함수 호출처럼 콜백 함수의 매개변수가 없어도 호출할 수 있으며, error 매개변수와 result 매개변수를 콜백 함수에서 사용하지 않을 뿐입니다.

또한 콜백 함수의 반환값이 void일 때는 어떠한 반환값이 와도 상관없습니다. 세 번째 함수처럼 true를 반환해도 해당 반환값은 무시됩니다.

배열의 forEach 메서드를 생각하면 좋습니다.

profile
백엔드 개발자

0개의 댓글