Skip to content

타입 추론 (Type Inference)

타입 추론이란 컴파일러가 코드의 문맥을 바탕으로 변수, 표현식, 함수 반환값 등의 타입을 자동으로 결정하는 프로세스를 말한다. 명시적인 타입 선언이 없어도 TypeScript는 내부 로직을 분석하여 적절한 타입을 유추한다. 타입 추론을 잘 활용하면 코드가 더 간결하고 가독성이 좋아진다.


타입 추론이 일어나는 시점 (명시할 필요 없는 경우)

TypeScript는 대입, 반환, 초기화, 연산 등의 컨텍스트를 통해 타입을 자동으로 유추한다.

ts
let count = 0; // number
const PI = 3.14; // 3.14 (literal type)

let message = "hello"; // string
const greet = "hello"; // "hello" (literal type)
  • let은 변할 수 있는 값으로 number, string 같은 일반 타입으로 추론
  • const는 불변 값으로 "hello", 3.14 같은 리터럴 타입으로 추론

1. 변수 타입

변수를 선언하면서 값을 초기화하면, TypeScript는 해당 값을 기반으로 타입을 추론한다.

ts
let myNumber = 5; // number
let myString = "Hello"; // string
let myBool = true; // boolean

myNumber = 10;
myNumber = "15"; // Error: 'string'은 'number'에 할당할 수 없음

⚠️ 암묵적 any

변수에 초기값이 없으면 타입을 추론할 수 없기 때문에 any로 추론된다.
이런 암묵적 any는 예기치 않은 오류의 원인이 될 수 있다.

ts
let value; // any
value = 10;
value = "Hello"; // 허용됨 (위험!)
  • tsconfig.json에서 "noImplicitAny": true로 설정하면 이런 암묵적 any 사용을 막을 수 있다.

2. 함수 반환 타입

TypeScript는 함수 본문 내부의 연산과 반환값을 분석해 자동으로 반환 타입을 추론한다.

ts
// :number 생략 가능
function add(x: number, y: number): number {
  return x + y;
}

// 추론에 의한 동일 동작
function add(x: number, y: number) {
  return x + y; // number로 추론
}

const n = add(10, 5); // n: number

// 문자열 반환
function addToString(x: number, y: number) {
  return `${x}${y}`; // string으로 추론
}

const s = addToString(10, 5); // s: string

💡 반환 타입 명시 습관

내부 함수나 짧은 코드에서는 생략 가능하지만,
API, 라이브러리, 공개 함수처럼 외부에서 사용하는 함수는 반환 타입을 명시하는 습관이 좋다.


3. 배열 & 객체 타입

배열이나 객체도 내부 요소나 프로퍼티를 기반으로 타입이 추론된다.

ts
let nums = [1, 2, 3, 4];
// nums: number[]

let user = { name: "Bin", age: 30 };
// user: { name: string; age: number }

nums.push("hello"); // Error
user.age = "30"; // Error

ts
let mixedValues = [1, 2, 3, "red", "green", "blue"];
// mixedValues: (string | number)[]

4. 기본값(Default Value) 기반 추론

함수 매개변수에 기본값을 지정하면, 그 값의 타입을 기준으로 추론한다.

ts
function greet(name = "Guest") {
  return `Hello, ${name}`;
}
// name: string, 반환값: string

5. 리터럴 타입과 const 추론

ts
let greeting = "hi"; // string
const greeting2 = "hi"; // "hi" (literal type)
  • let은 변경 가능성이 있어 일반 타입으로 추론
  • const는 변경 불가능하므로 리터럴 타입으로 추론

ts
let colors = ["red", "green"] as const;
// colors: readonly ["red", "green"]
  • as const를 사용하면 리터럴 그대로 타입을 고정할 수 있다.

6. 문맥적 타입 추론 (Contextual Typing)

타입스크립트는 함수 인자나 콜백 함수 내부에서 컨텍스트를 통해 타입을 추론한다.

ts
window.addEventListener("click", (event) => {
  console.log(event.clientX); // event: MouseEvent로 추론
});

const colors = ["red", "green", "blue"];
colors.forEach((color) => {
  console.log(color.toUpperCase()); // color: string으로 추론
});
  • 문맥적 추론은 특히 React, DOM 이벤트, 콜백 함수에서 자주 활용된다.

7. 타입 넓히기(Widening) & 좁히기(Narrowing)

TypeScript는 초기값을 기반으로 점차 넓은 타입으로 확장하는 경향이 있다.

ts
let x = "hello"; // string
const y = "hello"; // "hello" (literal type)
  • const더 좁은(literal) 타입
  • let더 넓은(general) 타입

ts
const person = {
  name: "Bin",
  age: 30,
} as const;

// name: "Bin", age: 30 (readonly)
  • as const를 사용하면 확장을 막고 리터럴 그대로 유지

정리

구분예시추론 결과
변수let a = 10;number
상수const a = 10;"10" (literal)
함수 반환return x + y;number
배열[1, 2, 3]number[]
혼합 배열[1, "a", true](string | number | boolean)[]
객체{ name: "Bin", age: 30 }{ name: string; age: number }
기본값 매개변수(name = "Guest")string
타입 미지정let value;any