| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 파이썬
- algorithm
- 자바스크립트
- 자바
- python algorithm
- Zerobase
- useState
- 알고리즘
- 운영체제
- 컴퓨터공학
- 글또
- execution context
- node.js
- typeScript
- 비동기
- codestates
- OS
- REACT
- NestJS
- 테스트코드
- 자료구조
- 코드스테이츠
- react 기초
- Python
- Operating System
- 개발공부
- 파이썬 알고리즘 인터뷰
- Computer Science
- JavaScript
- java
- Today
- Total
Back to the Basics
[typescript] Awaited type에 대해 알아보자 본문
[typescript] Awaited type에 대해 알아보자
9Jaeng 2026. 1. 17. 22:03최근에 사용하게 된 Awaited type에 대해 알아보고자 한다.
공식문서 링크 : https://www.typescriptlang.org/docs/handbook/utility-types.html#awaitedtype
Documentation - Utility Types
Types which are globally included in TypeScript
www.typescriptlang.org
Awaited type이란?
Awaited type은 await 했을 때 실제로 얻는 값의 타입을 의미한다. 이 타입은 typescript 4.5 버전에 새로 추가된 타입이다.
그럼 4.5 버전 이전에는 await 했을 때 실제 얻는 값의 타입을 확인할 수 없었을까? 한다면 그것은 아니다. 아래의 예시와 같이 4.5 이후나 이전에도 중첩된 Promise까지 실제 resolve 되는 결괏값 추론은 정상적으로 되었다
type E = Promise<number>;
type F = Promise<Promise<number>>;
type G = Promise<Promise<Promise<number>>>;
type H = Promise<PromiseLike<Promise<number>>>;
declare const e: E;
declare const f: F;
declare const g: G;
declare const h: H;
async function testFunc(){
const r1 = await e; // type 추론 number
const r2 = await f; // type 추론 number
const r3 = await g; // type 추론 number
const r4 = await h; // type 추론 number
}
그럼 이 타입이 추가된 이유는 무엇일까?
이 타입이 추가되었던 4.5 버전의 릴리즈 노트를 확인해 보면 이 타입이 도입된 배경을 알 수 있는데, Promise를 재귀적으로 완전히 해제(unwrapping)했을 때 실제로 남는 타입을 제대로 추론할 수 있도록 도입된 타입이다.
릴리즈 노트의 예시를 4.4 버전과 4.5 버전에서 각각 확인을 해보면 4.4 버전은 아래와 같은 type errror를 확인할 수 있고 4.5 버전은 result의 타입 추론을 확인할 수 있다.
릴리즈 노트 예시
declare function MaybePromise<T>(
value: T
): T | Promise<T> | PromiseLike<T>;
async function test(): Promise<[number, number]> {
const result = await Promise.all([
MaybePromise(1),
MaybePromise(2),
]);
return result;
}
4.4 버전
Type '[number | Promise<1>, number | Promise<2>]' is not assignable to type '[number, number]'.
Type 'number | Promise<1>' is not assignable to type 'number'.
Type 'Promise<1>' is not assignable to type 'number'.(2322)
const result: [number | Promise<1>, number | Promise<2>]
4.5 버전
const result: [number, number]
위와 같은 에러가 발생한 이유는 typescript 4.5 이전에는 Promise.all 타입 정의 자체가 튜플 내부 요소의 Promise 해제를 재귀적으로 표현하지 못했기 때문이다. MaybePromise <T>는 런타임에서는 결국 T로 resolve 되지만, 당시의 TypeScript 타입 시스템은 Promise.all이 반환하는 튜플 구조의 객 요소까지 Promise를 해제하지 못했다. 그 결과 [number, number]가 아닌 [number | Promise<number>, number | Promise<number>] 로 추론되어 타입 에러가 발생하였다.
typeScript 4.5에서는 Awaited<T> 타입이 도입되면서 “Promise를 완전히 해제했을 때의 최종 타입”을 재귀적으로 추론할 수 있게 되었고, 이를 기반으로 Promise.all, Promise.race 등의 타입 정의가 같이 개선되었다. 관련 PR
즉, 이 타입은 이전 typescript에서 추론하지 못했던 복잡한 Promise 구조를 재귀적으로 unwrapping 하여 최종적으로 얻는 값을 추론하기 위해 도입하였다.
언제 어떻게 사용하는가?
내가 사용하는 방식은 함수의 return type을 사용해야 할 때 이다.
예를 들면 아래와 같이 함수가 있다고 했을 때
async function fetchUser() {
return { id: 1, name: "jaeng" };
}
// 다른 곳에서 이 함수의 결과 타입이 필요
type User = ReturnType<typeof fetchUser>;
// ❌ 추론 타입 Promise<{ id: number; name: string }>
이렇게 하게 되면 추론 타입은 Promise가 된다. 내가 원하던 추론 타입은 { id: number; name: string }이다. 이럴 때 Awaited를 사용하면 원하는 타입 추론이 가능하다
type User = Awaited<ReturnType<typeof fetchUser>>;
// { id: number; name: string }
특히 TypeORM을 사용할 때, 레포지토리의 쿼리 결과 타입을 서비스 레이어에서 재사용하되 엔티티를 그대로 API DTO로 노출하지 않기 위해 레포지토리 반환 타입을 서비스 내부 타입으로 정의할 때에도 Awaited<ReturnType<…>>를 유용하게 사용할 수 있다.
이와 같이 함수의 반환타입을 정의할 때에도 사용할 수 있고 DTO 등을 만들 때에도 사용할 수도 있겠다.
여기서 ReturnType이란, 함수 선언에 명시된 반환 타입을 가져온다. 링크된 공식문서의 예제를 확인해 보자..!
'Programming Languages > Typescript & NestJS' 카테고리의 다른 글
| [NestJS] Monorepo로 구축하기 2 : 모노레포 구축 with NestJs 공식문서 (2) | 2025.09.01 |
|---|---|
| [NestJS] Monorepo로 구축하기 1 : pnpm workspace (0) | 2025.05.25 |
| [NestJs] NestJs의 IoC container 에 대하여 (2) | 2024.01.07 |
| [typescript] Type VS Interface (0) | 2024.01.07 |
| [NestJS] IoC(Inversion of Control) 제어의 역전과 DI(Dependcency) Injection)에 대해 알아보자 (1) | 2023.10.15 |