You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$fetch provides type safety for return types which is great. It would be greater if it optionally checks types for query and body parameters for internal API requests.
Below is a rough proposal:
Server routes optionally export QuerySchema and BodySchema.
-> Developer's responsibility
Generate necessary types for those routes /.nuxt/types/nitro.d.ts.
-> Below is an example.
Add types to /node_modules/nitropack/dist/index.d.ts
-> Below is a proposal.
// It would be better if `InternalApi` and the proposed `InternalApiQuerySchema` and `InternalApiQuerySchema`// are merged into one interface.// However separated interfaces are easier to implement for re-using the current code base.declaremodule'nitropack'{interfaceInternalApi{'/api/units': {'get': Awaited<ReturnType<typeofimport('../../server/api/units.get').default>>}}interfaceInternalApiQuerySchema{"/api/units": {get: import("../../server//api/units.get").QuerySchema;};}interfaceInternalApiBodySchema{"/api/units": {get: import("../../server//api/units.get").BodySchema;};}}
Related to TS error Excessive stack depth comparing types when trying to wrap $fetch #470. I get Excessive stack depth comparing types... error from TypeScript. This error is present even I copy-paste the types without changing them. The problem is caused by AvailableRouterMethod<R> type. If I switch it with RouterMethod, it works. In this case we sacrifice "method" safety. TBH, I prefer query and post safety to the "method"
safety.
a. Query and body parameters are much more error prone compared to a simple method name.
b. AvailableRouterMethod<R> type seems much more expensive compared to simple object types.
I don't know how to generate types /.nuxt/types/nitro.d.ts. I guess it would be easy to utilize already existing type generation function.
POC
Below is the POC: A composable for Nuxt representing Excessive stack... problem mentioned above.
POC Code
/server/api/units.get.ts
import{useValidatedQuery,useValidatedBody,z}from"h3-zod";importtype{H3Event}from"h3";constquerySchema=z.object({language: z.string()});constbodySchema=z.object({color: z.number()});exporttypeQuerySchema=z.infer<typeofquerySchema>;exporttypeBodySchema=z.infer<typeofbodySchema>;exportdefaulteventHandler(async(event: H3Event)=>{const{ language }=useValidatedQuery(event,querySchema);const{ color }=useValidatedBody(event,bodySchema);return{ color, language };});
/composables/useSafeFetch.ts
import{NitroFetchRequest,TypedInternalResponse,ExtractedRouteMethod,AvailableRouterMethod}from"nitropack";import{FetchOptions,FetchResponse}from"ofetch";importtype{InternalApiQuerySchema,InternalApiBodySchema}from"internal-api-schema";// Types from `/node_modules/nitropack/dist/index.d.ts`// ─── Added ───────────────────────────────────────────────────────────────────typeRequestSchema<Base,RextendsNitroFetchRequest,MextendsAvailableRouterMethod<R>=AvailableRouterMethod<R>>=RextendskeyofBase
? MextendskeyofBase[R]
? Base[R][M]
: never
: never;// ─── Modified ────────────────────────────────────────────────────────────────// Added `query` and `body`interfaceNitroFetchOptions<RextendsNitroFetchRequest,MextendsAvailableRouterMethod<R>=AvailableRouterMethod<R>>extendsOmit<FetchOptions,"query"|"body">{method?: Uppercase<M>|M;query?: RequestSchema<InternalApiQuerySchema,R,M>;body?: RequestSchema<InternalApiBodySchema,R,M>;}// ─── Not Changed ─────────────────────────────────────────────────────────────interface$Fetch<DefaultT=unknown,DefaultRextendsNitroFetchRequest=NitroFetchRequest>{<T=DefaultT,RextendsNitroFetchRequest=DefaultR,OextendsNitroFetchOptions<R>=NitroFetchOptions<R>>(request: R,opts?: O): Promise<TypedInternalResponse<R,T,ExtractedRouteMethod<R,O>>>;raw<T=DefaultT,RextendsNitroFetchRequest=DefaultR,OextendsNitroFetchOptions<R>=NitroFetchOptions<R>>(request: R,opts?: O): Promise<FetchResponse<TypedInternalResponse<R,T,ExtractedRouteMethod<R,O>>>>;create<T=DefaultT,RextendsNitroFetchRequest=DefaultR>(defaults: FetchOptions): $Fetch<T,R>;}constuseSafeFetch: $Fetch=(request,opts)=>$fetch(request,opts);useSafeFetch.raw=(request,opts)=>$fetch.raw(request,opts);useSafeFetch.create=(defaults)=>$fetch.create(defaults);exportdefaultuseSafeFetch;
Describe the feature
$fetch provides type safety for return types which is great. It would be greater if it optionally checks types for
query
andbody
parameters for internal API requests.Below is a rough proposal:
QuerySchema
andBodySchema
.-> Developer's responsibility
/.nuxt/types/nitro.d.ts
.-> Below is an example.
/node_modules/nitropack/dist/index.d.ts
-> Below is a proposal.
/server/api/product.units.ts
/.nuxt/types/nitro.d.ts
/node_modules/nitropack/dist/index.d.ts
Problems I stumbled upon:
Excessive stack depth comparing types
when trying to wrap$fetch
#470. I getExcessive stack depth comparing types...
error from TypeScript. This error is present even I copy-paste the types without changing them. The problem is caused byAvailableRouterMethod<R>
type. If I switch it withRouterMethod
, it works. In this case we sacrifice "method" safety. TBH, I preferquery
andpost
safety to the "method"safety.
a. Query and body parameters are much more error prone compared to a simple method name.
b.
AvailableRouterMethod<R>
type seems much more expensive compared to simple object types./.nuxt/types/nitro.d.ts
. I guess it would be easy to utilize already existing type generation function.POC
Below is the POC: A composable for Nuxt representing
Excessive stack...
problem mentioned above.POC Code
/server/api/units.get.ts
/composables/useSafeFetch.ts
/.nuxt/types/nitro.d.ts
Additional information
The text was updated successfully, but these errors were encountered: