박창준 2025. 7. 3. 15:16

타입스크립트 infer는 조건부 타입에서 미리 정의되지 않은 타입을 유연하게 정의할 수 있도록 도와주는 문법이다.

항상 조건부 타입 문법과 같이 사용되며 복잡한 타입 코드를 줄여준다.

infer의 예시

infer의 역할을 이해하기 위해서 간단한 코드를 살펴보자.

type ElementType<T> = T extends (infer ArrayElement)[] ? ArrayElement : T

위 코드는 ElementType 타입에 제네릭으로 넘긴 배열 타입의 요소를 반환한다. 예를들어서 제네릭에 string[] 타입을 넘기면 string을 반환하고 number[]를 넘기면 number 를 반환한다.

// 배열 타입을 넘긴 경우
type Result = ElementType<string[]>; // string
type Result = ElementType<number[]>; // number

// 배열 형태가 아닌 타입을 넘긴 경우
type Result = ElementType<boolean>; // boolean

infer는 뒤에 나오는 타입은 미리 정의되어 있지 않지만 마치 정의된 것 처럼 사용할 수 있다.

infer의 유효 범위

infer뒤에 나오는 타입은 조건부 문법 안에서만 사용될 수 있다고 했는데 이걸 실제로 한번 테스트 해보자.

type InferExample<T> = T extends infer Person ? Person : never;

이런 타입을 정의했고 조건부 문법 안에서 Person 타입을 정의했다.

type Result = InferExample<{ name: '캡팡' }>; // { name: string }

그럼 이렇게 {name: string}을 만족하면 Person이 만족할까?

type InferExample<T> = T extends infer Person ? Person : never;
type Result = InferExample<{ name: '캡팡' }>;

const capt: Person = {
  name: '캡팡'
};

위 사진과 같이 Persion 타입을 찾을 수 없다고 나온다.

infer로 함수 반환 타입을 추론하는 커스텀 타입 만들기

1단계: 조건부 타입 구조 만들기

type MyReturnType<T> = 
  T extends (...args: any[]) => any ? unknown : never;
  • t가 함수 타입이면 unknown 반환
  • 함수가 아니면 never

2단계: infer로 반환 타입 추론

type MyReturnType<T> = 
  T extends (...args: any[]) => infer R ? R : never;
  • T extends (...args: any[]) => infer R: T가 함수이고, 그 리턴 값을 R로 추론 한다면
  • R을 결과로 반환하게 만든다.
  • 아니면 never

zod에서 infer 활용법

Zod는 런타임 검증 도구지만, TypeScript와 결합되면 런타임 + 정적 타입 을 한번에 처리할 수 있다.

기본 사용 방법

import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number().optional(),
});

type User = z.infer<typeof UserSchema>;

이렇게 zod스키마로 부터 user type을 추출할 수 있다. 그러면 아래와 같이 타입을 사용할 수 있다.

type User = {
  id: string;
  name: string;
  age?: number;
}