[TIL / DAY 27] 타입 추론/표명/별칭 및 함수 오버로드

miseullang·2024년 11월 19일
post-thumbnail

✅ 강의 내용 정리

📍 타입 추론과 타입 표명


타입 추론 (type interface)

변수에 할당된 값을 보고, 그 변수의 타입을 추론하는 기능
변수를 선언할 때, 타입을 명시하지 않더라도 타입스크립트 엔진이 자동으로 타입을 추론하는 기능이다.

let num = 10; // 이렇게 해도 오류가 발생하지 않음

⇒ 함수 작성 시에도 값을 변수에 할당하고 있다면, 해당 값에 대한 타입 추론이 발생한다.

⇒ 함수의 매개변수는 타입 표명을 하지 않으면 any로 추론됨.

하지만 매개변수에 기본값을 지정해주면 타입 추론이 된다.

해당 변수에 할당되는 값을 보고 추론하는 것이기 때문에, 값이 할당되지 않은 변수는 any로 추론하는 것이다.

타입 표명 (type annotations)

타입을 명시하는 것

📍 인터섹션 (&)


여러 개의 타입을 모두 만족하게 하고 싶을 때 사용한다.

최소 2개 이상의 타입을 지정해야 하는데, 두 개 이상의 타입을 한번에 가질 수 있는 경우가 객체 정도밖에 없기 때문에, 객체에서 주로 활용된다.

{
  let value: { name: string } & { age: number } = {
    name: "Hello",
    age: 20,
  };
}
{
  // 인터섹션 타입은 any와 결합하면 any로 평가된다.
  let value: { name: string } & any = 10;
  console.log(value.toFixed(2));
}

📍 let과 const의 타입 추론


let은 재할당이 가능한 키워드, const는 재할당이 불가능한 키워드이므로 타입스크립트 엔진의 타입 추론이 조금 다르게 동작한다.

let은 number로 광범위하게 추론하지만, const는 10이라는 구체적인 수로 추론하는 것을 확인할 수 있다. 이렇게 추론되는 타입을 리터럴 타입이라고 한다.

let num = 10; // => number로 추론
 // 왜 let 키워드로 선언하나요?
const num1 = 10; // => 10으로 추론 (리터럴 타입)

📍 함수 오버로드


동일한 함수 이름에 대해 매개변수의 타입과 반환 타입을 다르게 지정할 수 있는 타입스크립트의 기능입니다. 함수를 더 타입 안전하게 사용할 수 있게 해줍니다.

  1. 오버로드 시그니처(선언부)와 구현부로 구성
  2. 시그니처는 함수의 타입만 선언하고, 실제 구현은 마지막 시그니처에서 한다
  3. 구현부는 모든 오버로드 시그니처의 타입을 포함할 수 있어야 한다

  function combine(a: number, b: number): number; // 오버로드 시그니처
  function combine(a: string, b: number): string; // 오버로드 시그니처
  function combine(a: number, b: string): string; // 오버로드 시그니처
  function combine(a: number | string, b: number | string): number | string {
    if (typeof a === "number" && typeof b === "number") return a + b;
    else return `${a}${b}`;
  }

사용 목적

  • 하나의 함수로 다양한 타입의 매개변수를 처리할 때 타입 안전성 확보
  • 함수 호출 시 타입에 따른 명확한 반환 타입 보장
  • 매개변수 타입에 따른 다른 동작을 타입 시스템에 명시적으로 알림

🧀 추가 개념 / 콜 시그니처와 오버로드 시그니처


주말에 봤던 강의에서는 콜 시그니처 개념에 대해서만 다뤘는데, 오늘은 오버로드 시그니처에 대해 배웠다. 두 개념에 약간 혼동이 와서 팀원분들의 도움을 받아 개념을 정리했다.

콜 시그니처

함수의 타입을 정의하는 방법. 함수의 매개변수와 반환 타입을 미리 정의하는 것.
(함수 위에 마우스를 올렸을 때 보게 되는 것)

  // 콜 시그니처 (call signatures)
  type Add = (a: number, b: number) => number; // 콜 시그니처 정의하기
  const add: Add = (a, b) => a + b; // 내가 정의한 타입 사용하기

오버로드 시그니처

여러 개의 콜 시그니처를 조합한 형태로, 각 매개변수 조합의 경우의 수에 따라 반환 값의 타입을 지정해주는 방식.

function combine(a: number, b: number): number; // 오버로드 시그니처
function combine(a: string, b: number): string; // 오버로드 시그니처
function combine(a: number, b: string): string; // 오버로드 시그니처
function combine(a: number | string, b: number | string): number | string {
  if (typeof a === "number" && typeof b === "number") return a + b;
    else return `${a}${b}`;
}

→ 한 마디로 콜 시그니처는 사용자 정의 타입이라고 볼 수 있고, 오버로드 시그니처는 구현부에 대한 반환 값의 타입을 지정해주는 것이므로 목적과 구현 방식이 약간 다르다.

콜 시그니처는 정의해두면 어디에든 계속 사용이 가능하지만, 오버로드 시그니처는 함수에 결합된 형태이므로 해당 함수 외에는 재활용이 불가능하다는 점도 다르다.

🧀 추가 개념 / 타입 별칭(type alias) 과 콜 시그니처


위에서 콜 시그니처에 대해서 알아봤는데… 강사님이 타입 별칭이라고 알려주는 코드가 콜 시그니처와 너무 유사한 형태였다. 동일 개념에 대한 명칭이 다른 건가? 생각했는데 타입 별칭이 콜 시그니처를 포함하는 관계였다.

// 나만의 타입을 짓는 방법 -> number, string, object, boolean ...
// 타입 별칭(type alias)
type Input = boolean | number | string;

타입 별칭

  • 타입에 대한 이름을 지정하는 문법
  • 모든 종류의 타입에 대해 별칭을 만들 수 있음

콜 시그니처

  • 함수의 타입을 정의하는 특별한 문법

즉, 타입 별칭은 자료형을 구분짓지 않는 사용자 정의 타입이라면, 콜 시그니처는 함수에 한정되는 개념이다.




💭 회고

요즘 집중도 잘 안 되고 시간 관리도 잘 못하고 있는 것 같아서 조금 우울했는데 오늘 배운 내용을 복습하고 정리하면서 오랜만에 뿌듯함을 느꼈다!

전부터 타입스크립트를 배우고 싶었는데 여건 상 계속 미루다가 드디어 접하게 돼서 재밌게 공부하는 중이다. 하지만 재밌다는 게 쉬운 건 아니라서 빠르게 코드를 짤 수 있도록 속도 개선이 필요할 것 같다.

오늘 강사님도 코테의 중요성에 대해 말씀해주시고, 매니저님도 독려해주셨다.

저도 알지만 오늘도 5시에 잤는걸료… 일정 조정을 해야 맞는건지, 내 의지나 노력이 부족한건지 판단이 안 서서 멘토링을 신청했다. 일단 가보자고

profile
괴발개발 💻

0개의 댓글