Weldawadyathink
Weldawadyathink2mo ago

Error with AppRouter type mismatch in Deno

Hi everyone! I am trying to fix some type issues with a tRPC project. I am using Deno 2.0. The server and client are separate projects (but in a monorepo). The server is using the hono middleware to host the /trpc endpoint. The client is a vite react static site. I am using the react query integration. Here is the weird part: Everything is actually fully functional. The vite frontend can tRPC query the backend perfectly fine. However the frontend is complaining about type mismatches. Not having working types kinda defeats the purpose of tRPC. client/src/utils/api.ts
import { createTRPCReact } from "@trpc/react-query";
import type { AppRouter } from "../../../server/routers/_app.ts";

export const api = createTRPCReact<AppRouter>();
import { createTRPCReact } from "@trpc/react-query";
import type { AppRouter } from "../../../server/routers/_app.ts";

export const api = createTRPCReact<AppRouter>();
This is where I get the first type issue. I think solving this will solve all the issues. I get the error on the <AppRouter> type. This post went over the length limit, so more details in the next post.
2 Replies
Weldawadyathink
WeldawadyathinkOP2mo ago
Entire error message:
Deno: Type
CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { book: CreateRouterInner<...>; }>
does not satisfy the constraint Router<AnyRouterDef<AnyRootConfig, any>>
The types returned by createCaller(...) are incompatible between these types.
Type 'DecoratedProcedureRecord<{ book: CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { ...; }>; }> & { ...; }' is not assignable to type 'DecoratedProcedureRecord<any> & { query: inferHandlerFn<any>; mutation: inferHandlerFn<any>; subscription: inferHandlerFn<any>; }'.
Type
DecoratedProcedureRecord<{ book: CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { ...; }>; }> & { ...; }
is not assignable to type DecoratedProcedureRecord<any>
Property query is incompatible with index signature.
Type inferHandlerFn<{}> is not assignable to type
DecoratedProcedureRecord<any> | DecorateProcedure<any>
Type inferHandlerFn<{}> is not assignable to type DecorateProcedure<any>
Types of parameters path and input are incompatible.
Type any is not assignable to type never
Deno: Type
CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { book: CreateRouterInner<...>; }>
does not satisfy the constraint Router<AnyRouterDef<AnyRootConfig, any>>
The types returned by createCaller(...) are incompatible between these types.
Type 'DecoratedProcedureRecord<{ book: CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { ...; }>; }> & { ...; }' is not assignable to type 'DecoratedProcedureRecord<any> & { query: inferHandlerFn<any>; mutation: inferHandlerFn<any>; subscription: inferHandlerFn<any>; }'.
Type
DecoratedProcedureRecord<{ book: CreateRouterInner<RootConfig<{ ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>, { ...; }>; }> & { ...; }
is not assignable to type DecoratedProcedureRecord<any>
Property query is incompatible with index signature.
Type inferHandlerFn<{}> is not assignable to type
DecoratedProcedureRecord<any> | DecorateProcedure<any>
Type inferHandlerFn<{}> is not assignable to type DecorateProcedure<any>
Types of parameters path and input are incompatible.
Type any is not assignable to type never
That doesn't have any formatting, so here is the bit that looks the most important to me:
Type inferHandlerFn<{}> is not assignable to type DecorateProcedure<any>
Types of parameters path and input are incompatible.
Type any is not assignable to type never
Type inferHandlerFn<{}> is not assignable to type DecorateProcedure<any>
Types of parameters path and input are incompatible.
Type any is not assignable to type never
The server section has no type errors. It is setup according to the trpc v10 documentation. server/main.ts
import { Hono } from "hono";
import { serveStatic } from "hono/deno";
import { trpcServer } from "@hono/trpc-server";
import { appRouter } from "./routers/_app.ts";
import { cors } from "hono/cors";

const app = new Hono();

app.use(cors());

app.use(
"/trpc/*",
trpcServer({
endpoint: "/trpc",
router: appRouter,
}),
);

app.use(
"*",
serveStatic({
root: "./dist/",
}),
);

export default app;
import { Hono } from "hono";
import { serveStatic } from "hono/deno";
import { trpcServer } from "@hono/trpc-server";
import { appRouter } from "./routers/_app.ts";
import { cors } from "hono/cors";

const app = new Hono();

app.use(cors());

app.use(
"/trpc/*",
trpcServer({
endpoint: "/trpc",
router: appRouter,
}),
);

app.use(
"*",
serveStatic({
root: "./dist/",
}),
);

export default app;
server/routers/_app.ts
import { router } from "../trpc.ts";

import { bookRouter } from "./book.ts";

export const appRouter = router({
book: bookRouter,
});

export type AppRouter = typeof appRouter;
import { router } from "../trpc.ts";

import { bookRouter } from "./book.ts";

export const appRouter = router({
book: bookRouter,
});

export type AppRouter = typeof appRouter;
/server/routers/book.ts
import { router, publicProcedure } from "../trpc.ts";
import { z } from "zod";

export const bookRouter = router({
hello: publicProcedure.input(z.string().nullish()).query(({ input }) => {
return `Hello, ${input ?? "World"}!`;
}),
test: publicProcedure.query(() => "Hi there"),
});
import { router, publicProcedure } from "../trpc.ts";
import { z } from "zod";

export const bookRouter = router({
hello: publicProcedure.input(z.string().nullish()).query(({ input }) => {
return `Hello, ${input ?? "World"}!`;
}),
test: publicProcedure.query(() => "Hi there"),
});
Update: I threw together a minimal replication using Bun. It still works, and all the type errors are gone. So I think this issue might stem from Deno. I am going to look into submitting this as a bug report to deno.
b0ngl0rd
b0ngl0rd2mo ago
It might be typescript related. I'm also having tons of issues with autocomplete in a monorepo with a NextJS+tRPC project and api client project. I'm instead getting either "any" type or a typescript property overwrite error depending on whether I import directly or through a barrel file.