타입 추론 (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 |