TypeScript 환경에서 서버 액션(getPosts, createComment 등)을 다루다 보면 반환 타입을 정확히 정의하기가 꽤 귀찮습니다.
getPosts() 함수가 있습니다.
export async function getPosts() {
return await prisma.post.findMany({
include: { author: true, comments: true, likes: true, _count: true },
});
}
- 이 함수는 비동기(async)이기 때문에 반환 타입이 Promise<Post[]> 형태입니다.
- 하지만 이걸 컴포넌트에서 재사용하려면, 정확한 타입을 일일이 써줘야 합니다.
예를 들어 다음처럼 쓸 수 있겠죠.
type Post = {
id: string;
content: string;
author: {
id: string;
name: string;
username: string;
image?: string;
};
// ...기타 필드
};
- 하지만 이렇게 매번 타입을 수동으로 작성하면,
- DB 스키마가 바뀔 때마다 수동으로 고쳐야 하는 문제가 생깁니다.
ReturnType — 함수 반환 타입 추출
TypeScript는 함수의 반환 타입을 자동으로 추론할 수 있는 유틸리티 타입 ReturnType<T>를 제공합니다.
type PostsPromise = ReturnType<typeof getPosts>;
- 위 코드는 PostsPromise를 Promise<Post[]>로 인식합니다.
- 하지만 우리는 Promise가 아닌 실제 데이터(Post[])가 필요합니다.
Awaited — Promise 안의 타입 꺼내기
Awaited<T>는 Promise로 감싸진 타입에서 실제 결과값을 추출합니다.
type Posts = Awaited<ReturnType<typeof getPosts>>;
- 이제 Posts는 Post[] 타입이 됩니다.
- 즉, getPosts()를 실행하고 나서 resolve된 값의 타입을 정확히 표현할 수 있게 된 것이죠.
배열에서 단일 요소 타입 뽑기
Posts는 배열 타입이므로, Posts[number]를 사용해 각 요소(게시글 하나)의 타입을 가져올 수 있습니다.
type Post = Posts[number];
- 이 한 줄 덕분에 PostCard 같은 컴포넌트에서 안전하게 단일 게시글 타입을 사용할 수 있습니다.
function PostCard({ post, dbUserId }: { post: Post; dbUserId: string | null }) {
// post는 이제 getPosts()의 단일 아이템 타입과 정확히 일치!
}
| 코드 | 설명 |
| ReturnType<typeof getPosts> | getPosts() 함수의 반환 타입 (Promise) |
| Awaited<returntype></returntype | Promise가 resolve된 실제 값 (Post[]) |
| Posts[number] | 배열의 한 요소, 즉 Post 한 개 |
예시
type Posts = Awaited<ReturnType<typeof getPosts>>;
type Post = Posts[number];
function PostCard({ post, dbUserId }: { post: Post; dbUserId: string | null }) {
return (
<div>
<h2>{post.author.name}</h2>
<p>{post.content}</p>
</div>
);
}
- 이렇게 작성하면 DB 스키마가 바뀌거나 getPosts() 반환값이 수정되어도, TypeScript가 자동으로 타입을 추적해줍니다.
'개발 공부' 카테고리의 다른 글
| TreeNode (0) | 2025.12.08 |
|---|---|
| 연결 리스트(Node) (0) | 2025.12.06 |
| shadcn/ui (2) example) Button · Card (0) | 2025.11.17 |
| shadcn/ui (1) (0) | 2025.11.16 |
| Prisma CRUD 예시 (0) | 2025.11.12 |