타입스크립트 (6) 함수와 타입

김태완·2024년 11월 20일
post-thumbnail

함수의 타입을 정의하는 방법

  • 따라서 함수의 타입은 위와 같이 매개 변수와 반환값의 타입으로 결정된다.

화살표 함수 타입 정의하기

  • 화살표 함수의 타입 정의 방식도 함수 선언식과 동일하다.
  • 화살표 함수 역시 반환값의 타입은 자동으로 추론된다.

매개변수 기본값 설정하기

  • 함수의 매개변수에 기본값이 설정되어있으면 타입이 자동으로 추론된다. 이럴 경우 타입 정의를 생략해도 된다.
  • 이때, 기본값과 다른 타입으로 매개변수의 타입을 정의하면 오류가 발생한다.
  • 그리고 기본값과 다른 타입의 값을 인수로 전달해도 오류가 발생한다.

선택적 매개변수 설정하기

  • 매개변수의 이름뒤에 물음표(?)를 붙여주면 선택적 매개변수가 되어 생략이 가능하다.
  • 위 코드의 tall 같은 선택적 매개변수의 타입은 자동으로 undefined와 유니온 된 타입으로 추론된다. 따라서 tall의 타입은 현재 number | undefined이 된다. 그러므로 이 값이 number 타입의 값일 거라고 기대하고 사용하려면 다음과 같이 타입 좁히기가 필요하다.
  • 그리고 이 선택적 매개변수는 필수 매개변수 앞에 올 수 없다.

나머지 매개변수

  • getSum 함수는 나머지 매개변수 rest로 배열 형태로 number 타입의 인수들을 담은 배열을 전달받는다.
  • 이때 만약 나머지 매개변수의 길이를 고정하고 싶다면 다음과 같이 튜플 타입을 이용해도 된다.

함수 타입 표현식과 호출 시그니처

함수 타입 표현식

  • 함수 타입을 타입 별칭과 함께 별도로 정의할 수 있다. 이를 함수 타입 표현식(Function Type Expression)이라고 부른다.
  • 이렇게 함수 타입 표현식을 이용하면 함수 선언 및 구현 코드와 타입 선언을 분리할 수 있어 유용하다.
  • 위 코드처럼 여러개의 함수가 동일한 타입을 갖는 경우에 요긴하게 사용된다.
  • 이렇게 함수 타입 표현식을 이용하면 간결하게 만들 수 있다.
  • 또한, 동일한 타입의 함수가 추가되어도 타입 주석을 이용해 타입 정의만 해주면 되기때문에 편리하다.
  • Operation 타입 별칭 대신 표현식을 그대로 넣어주어서 한줄로도 표현 가능하다.

호출 시그니처(Call Signatured)

  • 함수 타입 표현식과 동이랗게 함수의 타입을 별도로 정의하는 방식이다.
  • 자바스크립트에서는 함수도 객체이기 때문에, 위 코드처럼 객체를 정의하듯 함수의 타입을 별도로 정의할 수 있다.
  • 참고로 이때 다음과 같이 호출 시그니쳐 아래에 프로퍼티를 추가 정의하는 것도 가능하다. 이렇게 할 경우 함수이자 일반 객체를 의미하는 타입으로 정의되며 이를 하이브리드 타입이라고 부른다.

함수 타입의 호환성

  • 함수 타입의 호환성이란 특정 함수 타입을 다른 함수 타입으로 취급해도 괜찮은지 판단하는 것을 의미한다.
  • 2가지 기준으로 함수 타입의 호환성을 판단하게 된다.
    • 두 함수의 반환값 타입이 호환되는가?
    • 두 함수의 매개변수의 타입이 호환되는가?

기준 1. 반환값 타입이 호환되는가?

  • A와 B 함수 타입이 있다고 가정할 때 A 반환값 타입이 B 반환값 타입의 슈퍼타입이라면 두 타입은 호환된다.
  • A의 반환값 타입은 Number, B의 반환값 타입은 Number Literal 이다. 따라서 변수 a에 b를 할당하는 것은 가능하나 반대로는 불가능 하다. (다운캐스트)

기준 2. 매개변수의 타입이 호환되는가?

2-1. 매개변수의 개수가 같을때

  • 두 함수 타입 C와 D가 있다고 가정할 때, 두 타입의 매개변수의 개수가 같다면 C 매개변수의 타입이 D 매개변수 타입의 서브 타입일 때에 호환된다.
  • C 매개변수의 타입은 Number, D 매개변수의 타입은 Number Literal 입니다. 따라서 C 매개변수의 타입이 D 매개변수의 슈퍼타입이므로 D를 C로 취급하는것은 불가능하나 반대로는 가능하다.
  • 이는 반환값 타입과 반대된다. 마치 다운캐스팅을 허용하는 것 같다. (?? 객체 부분으로 더 살펴보자)
  • animalFunc에 dogFunc를 할당하는 것은 불가능하다. dogFunc의 매개변수 타입이 animalFunc 매개변수 타입보다 작은 서브타입이기 때문이다. 반대로는 가능하다.(업캐스팅인데 왜???)
  • animalFunc = dogFunc를 코드로 표현해보면 다음과 같다.
  • animalFunc 타입의 매개변수 타입은 Animal 타입이다. 그러나 dogFunc 함수 내부에서는 name과 color 프로퍼티에 접근한다.\
  • 따라서 이렇게 할당이 이루어지게 되면 animal.color처럼 존재할거라고 보장할 수 없는 프로퍼티에 접근하게 된다.
  • 반대로 dogFunc = animalFunc를 코드로 표현하면 다음과 같다.
  • dogFunc 함수의 매개변수는 Dog 타입이다. 그리고 animalFunc 함수 내부에서는 name 프로퍼티에만 접근한다. 이 코드는 안전하다.

    그러므로 두개의 함수 타입 C와 D가 있을 때 두 매개변수의 개수가 같을 경우 D를 C로 취급하려면 C 매개변수의 타입이 D 매개변수 타입의 서브 타입이어야 한다.
    매개변수를 기준으로 업캐스팅은 안된다!

2-2. 매개변수의 개수가 다를때

  • 매개변수의 개수가 다를때는 할당하려는 함수의 매개변수의 개수가 더 적을때만 가능하다.
  • 물론 매개변수의 타입들이 다르다면 오류 발생한다!

함수 오버로딩

  • 함수 오버로딩이란 하나의 함수를 매개변수의 개수나 타입에 따라 다르게 동작하도록 만드는 문법이다.
  • 타입스크립트에서 함수 오버로딩을 구현하려면 먼저 다음과 같이 버전별 오버로드 시그니쳐를 만들어줘야 한다.
  • 이렇게 구현부 없이 선언부만 만들어둔 함수를 ‘오버로드 시그니쳐’라고 한다.
  • 위 코드에서는 2개의 오버로드 시그니쳐를 만들었으며 각각 함수의 버전을 의미한다. 위 코드의 func 함수는 매개변수를 1개 받는 버전과 3개 받는 2개의 버전이 있다고 알리는 것과 같다.
  • 오버로드 시그니쳐를 만들었다면 다음으로는 구현 시그니쳐를 만들어줘야 한다.
  • 구현 시그니쳐는 실제로 함수가 어떻게 실행될 것인지를 정의하는 부분이다.
  • 구현 시그니쳐의 매개변수 타입은 모든 오버로드 시그니쳐와 호환되도록 만들어야 한다.
  • 따라서 위 코드에서는 매개변수 b와 c를 선택적 매개변수로 만들어 매개변수를 하나만 받는 첫번째 오버로드 시그니쳐와도 호환되도록 만들었다.

사용자 정의 타입가드

  • 사용자 정의 타입가드란 참 또는 거짓을 반환하는 함수를 이용해 우리 입맛대로 타입 가드를 만들 수 있도록 도와주는 타입스크립트의 문법이다.
  • 그런데 이렇게 in 연산자를 이용해 타입을 좁히는 방식은 좋지않다.
  • 예를 들어 만약 Dog 타입의 프로퍼티가 다음과 같이 중간에 이름이 수정되거나 추가 또는 삭제될 경우에는 타입 가드가 제대로 동작하지 않을수도 있다.
  • 그래서 다음과 같이 커스텀 타입 가드를 만들어 타입을 좁혀보자.
  • isDog 함수는 매개변수로 받은 값이 Dog 타입이라면 true 아니라면 false를 반환한다. 이때 반환값의 타입으로 animal is Dog 를 정의하면, 이 함수가 true를 반환하면 조건문 내부에서는 이 값이 Dog 타입임을 보장한다는 의미이다.
  • 따라서 warning 함수에서 isDog 함수를 호출해 매개변수의 값이 Dog 타입인지 확인하고 타입을 좁힐 수 있다.

이미지 출처: <한 입 크기로 잘라먹는 타입스크립트>
https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%ED%81%AC%EA%B8%B0-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8?inst=68d752f7&utm_source=instructor&utm_medium=referral&utm_campaign=inflearn_%ED%8A%B8%EB%9E%98%ED%94%BD_promotion-link

profile
중고

0개의 댓글