본문 바로가기
카테고리 없음

TypeScript 28강: 고급 타입 추론 및 타입 호환성 이해하기

by mystory55776 2025. 5. 28.

타입스크립트의 타입 추론(Type Inference)이란?

타입스크립트(TypeScript)의 타입 추론은 명시적으로 타입을 지정하지 않아도, 코드의 문맥을 분석하여 타입을 자동으로 결정하는 기능입니다. 이로 인해 코드가 간결해지고, 생산성이 향상됩니다.

let name = "TypeScript"; // string으로 추론
let count = 10;          // number로 추론

명시적으로 : string 또는 : number와 같이 선언하지 않아도, 변수에 할당된 값을 기준으로 타입이 결정됩니다.

타입 추론의 주요 전략

타입스크립트는 다양한 전략을 통해 타입을 추론합니다.

  • 초기화 추론 (Initialization Inference): 변수 선언 시 초기값을 통해 추론
  • 기본값 추론 (Default Parameter Inference): 함수의 기본값을 기준으로 추론
  • 컨텍스트 기반 추론 (Contextual Typing): 이벤트 핸들러 등에서 문맥 기반 추론
window.addEventListener("click", (e) => {
  console.log(e.clientX); // e는 MouseEvent로 추론됨
});

이러한 추론 기능은 코드 작성 시 IDE의 자동 완성과 타입 검사의 정확도를 높여줍니다.

타입 넓히기(Widening)와 좁히기(Narrowing)

타입스크립트는 값을 기반으로 타입을 더 구체화하거나 일반화할 수 있습니다.

  • 넓히기 (Widening): const가 아닌 let으로 선언 시, 타입이 일반적인 형태로 추론됨
  • 좁히기 (Narrowing): 조건문 등을 통해 타입을 구체적으로 좁힐 수 있음
let status = "success";  // string으로 넓혀짐
const fixed = "success"; // "success" 리터럴 타입으로 좁혀짐

변수를 리터럴 타입으로 고정하고 싶다면 constas const를 사용합니다.

타입 호환성(Type Compatibility)이란?

타입 호환성은 하나의 타입을 다른 타입에 할당할 수 있는지 여부를 결정하는 기준입니다. TypeScript는 구조적 타입 시스템을 기반으로 하며, 두 타입의 구조가 일치하면 호환된다고 판단합니다.

interface Animal {
  name: string;
}

interface Dog {
  name: string;
  breed: string;
}

let animal: Animal;
let dog: Dog = { name: "Buddy", breed: "Golden Retriever" };

animal = dog; // OK: Dog는 Animal의 구조를 포함함

반대로, animaldog에 할당하면 오류가 발생합니다. 누락된 속성이 있기 때문입니다.

함수의 타입 호환성

함수는 매개변수의 수와 타입, 반환 타입에 따라 호환성이 결정됩니다.

type FuncA = (a: number) => void;
type FuncB = (a: number, b: number) => void;

let fa: FuncA = (x) => {};
let fb: FuncB = (x, y) => {};

fa = fb; // OK
// fb = fa; // Error: 두 번째 매개변수 누락

TypeScript는 매개변수가 더 적은 쪽은 더 많은 쪽에 할당 가능하다고 판단합니다.

타입 호환성에서의 특별 규칙

  • void 반환 함수는 다른 반환값이 있어도 할당 가능
  • 제네릭 타입은 구조가 같으면 호환 가능
  • readonly 속성이나 private 필드는 호환성에 영향을 줌
type ReadA = { readonly name: string };
type MutB = { name: string };

// let a: ReadA = { name: "TS" };
// let b: MutB = a; // Error: readonly 무시 불가

타입 호환성 판단 기준 요약

타입스크립트의 호환성은 다음과 같은 기준을 따릅니다.

  • 모든 필드가 포함되어야 한다
  • 매개변수 수는 적은 쪽이 많은 쪽에 할당 가능
  • 기본적으로 구조적 타이핑을 따른다

strict 모드와 타입 추론

tsconfig.json에서 "strict": true를 설정하면 타입 검사가 더 엄격해집니다. 암시적 any 금지, null 검사 강화 등으로 타입 추론이 정밀해지고, 코드의 안전성이 높아집니다.

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

실무에서는 strict 모드를 사용하는 것이 권장됩니다.

실전 예제: 조건부 타입에서의 추론

타입스크립트는 조건부 타입에서도 추론 기능을 제공합니다.

type GetReturnType = T extends (...args: any[]) => infer R ? R : never;

type Result = GetReturnType<() => string>; // string

infer 키워드는 조건부 타입에서 특정 타입을 추론할 수 있게 해주며, 복잡한 타입 변형 작업에 유용합니다.

결론: 타입 추론과 호환성은 타입스크립트의 핵심

타입 추론은 타입스크립트의 편의성과 강력함을 동시에 제공하며, 타입 호환성은 타입 간의 관계를 명확하게 정의합니다. 이 두 개념을 이해하고 활용하면, 복잡한 타입 시스템에서도 안정적이고 유연한 코드를 작성할 수 있습니다.

실무에서의 안전한 코드 작성을 위해서는 타입 추론 결과를 이해하고, 필요한 경우 명시적으로 타입을 지정하는 습관이 중요합니다. 또한 strict 모드를 활용해 가능한 오류를 사전에 방지하는 것이 바람직합니다.