#Next 13 API fetch return types

12 messages · Page 1 of 1 (latest)

frigid moth
#

What is the appropriate way to cast my data to the correct return types of Next APIs?

Currently, I have:

import { GET } from '@/app/api/todos/route';

async function MyPage() {
  const data: Awaited<ReturnType<typeof GET>> = await fetch('http://localhost:3000/api/todos').then((r) => r.json());

  return <> </>
}

This is close, but data ends up as:

const data: NextResponse<{
    id: number;
    name: string;
}[]>

This isn't iterable. How would I unwrap the NextResponse part of it?

rigid sirenBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

      🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in <id:customize>

      ✅ You can mark a message as the answer for your post with `Right click -> Apps -> Mark Solution`
      (if you don't see the option, try refreshing Discord with Ctrl + R)
sturdy stone
#

I would just just tRPC, to be honest. It provides e2e type-safety and has almost no overhead perf wise whatsoever.

frigid moth
#

I'm familiar with TRPC.

I'm just asking from a foundational perspective, there should be a really simple TS solution, I'm guessing.

For instance, I could wrap the internals of GET in an exported function, call the function inside of GET and use that function for my type declaration, and it would work, just wondering if there's a way where I can do it with GET directly.

Similar to this project that worked with the pages directory:
https://github.com/alii/nextkit-demo/blob/db7106a99e796b19aebbc2746dea38a16eaaad96/src/pages/index.tsx#L7

GitHub

Demo app usage of nextkit. Contribute to alii/nextkit-demo development by creating an account on GitHub.

sturdy stone
#

Idk just thinking out loud lol

#

Still would be nicer and easier to use tRPC tho 🙃

frigid moth
#

Yeah, I gotcha, I'm not denying trpc would be better, I'm not building a prod app, not really a 'whats the best way to do this?' question, just more a curious TS one

vapid crown
#

For instance, I could wrap the internals of GET in an exported function, call the function inside of GET and use that function for my type declaration, and it would work, just wondering if there's a way where I can do it with GET directly.
yeah that would be ideal solution, you don't want to add an extra request to your own server if you can execute the logic directly in your RSC

as for the question itself, the easiest solution would be to export your own type from the route handler and use it to type the response, like this:

import { ResponseX } from '@/app/api/todos/route'

// This probably shouldn't be in this file
const get = async <T,>(url) => {
  const res = await fetch(url)
  const data = await res.json() as T
  return data
}

async function Page() {
  const data = await get<ResponseX>('...')
}
#

if you want to infer the response from the return of the route handler methods, like GET, then it is harder because the Response class doesn't contain the type information of the body of the response. so you would need to wrap these methods with your own function that contains the type info