H
Hono7mo ago
lessquo

ContextVariableMap not recognized during build from other package in monorepo

I created src/hodo.d.ts file in my Hono project:
import { User } from './schema';

declare module 'hono' {
interface ContextVariableMap {
me: User;
}
}
import { User } from './schema';

declare module 'hono' {
interface ContextVariableMap {
me: User;
}
}
Then, the type was inferred out of the box:
import { Hono } from 'hono';

export const users = new Hono().get('/me', c => c.json(c.var.me));
import { Hono } from 'hono';

export const users = new Hono().get('/me', c => c.json(c.var.me));
And, I configured the RPC feature in my React project:
import { ApiType } from 'api/src';
import { hc } from 'hono/client';
import { getIdToken } from './firebase';

export const api = hc<ApiType>(import.meta.env.VITE_API_URL, {
headers: async () => ({ Authorization: `Bearer ${await getIdToken()}` }),
});
import { ApiType } from 'api/src';
import { hc } from 'hono/client';
import { getIdToken } from './firebase';

export const api = hc<ApiType>(import.meta.env.VITE_API_URL, {
headers: async () => ({ Authorization: `Bearer ${await getIdToken()}` }),
});
It worked like a charm. but then I tried build command and encountered an error:
$ tsc && vite build --mode dev
../api/src/routes/users.ts:3:56 - error TS2769: No overload matches this call.
Overload 1 of 2, '(object: JSONValue | {}, status?: StatusCode | undefined, headers?: HeaderRecord | undefined): Response & TypedResponse<never, StatusCode, "json">', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'JSONValue | {}'.
Overload 2 of 2, '(object: JSONValue | {}, init?: ResponseInit | undefined): Response & TypedResponse<never, StatusCode, "json">', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'JSONValue | {}'.

3 export const users = new Hono().get('/me', c => c.json(c.var.me));
$ tsc && vite build --mode dev
../api/src/routes/users.ts:3:56 - error TS2769: No overload matches this call.
Overload 1 of 2, '(object: JSONValue | {}, status?: StatusCode | undefined, headers?: HeaderRecord | undefined): Response & TypedResponse<never, StatusCode, "json">', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'JSONValue | {}'.
Overload 2 of 2, '(object: JSONValue | {}, init?: ResponseInit | undefined): Response & TypedResponse<never, StatusCode, "json">', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'JSONValue | {}'.

3 export const users = new Hono().get('/me', c => c.json(c.var.me));
Does ContextVariableMap type declaration not work with RPC feature?
25 Replies
lessquo
lessquoOP7mo ago
I think I found a solution. src/hono.d.ts:
import { User } from './schema';

export type Variables = {
me: User;
};

declare module 'hono' {
interface ContextVariableMap extends Variables {}
}
import { User } from './schema';

export type Variables = {
me: User;
};

declare module 'hono' {
interface ContextVariableMap extends Variables {}
}
src/index.ts:
import { Hono } from 'hono';
import { Variables } from './hono';
import { users } from './routes/users';

const app = new Hono<{ Variables: Variables }>();

const route = app.route('/users', users);

export default app;

export type ApiType = typeof route;
import { Hono } from 'hono';
import { Variables } from './hono';
import { users } from './routes/users';

const app = new Hono<{ Variables: Variables }>();

const route = app.route('/users', users);

export default app;

export type ApiType = typeof route;
Nico
Nico7mo ago
Did you add export {} to your hono.d.ts file? Otherwise it won’t be global
lessquo
lessquoOP7mo ago
I didn't and it works well?! don't know what the difference is
Nico
Nico7mo ago
That did work or it didn’t?
lessquo
lessquoOP7mo ago
No difference whether adding it or not. both works.
Nico
Nico7mo ago
This is with the original code in there not the Variable type correct?
lessquo
lessquoOP7mo ago
I don't understand your question. I'm totally new to Hono
Nico
Nico7mo ago
I’m asking if you testing it with the original code you provided. Not the updated one
lessquo
lessquoOP7mo ago
I did with the updated one. I'll try your suggestion with the original code
Nico
Nico7mo ago
Yes
lessquo
lessquoOP7mo ago
import { User } from './schema';

// export type Variables = {
// me: User;
// };

declare module 'hono' {
// interface ContextVariableMap extends Variables {}
interface ContextVariableMap {
me: User;
}
}

export {};
import { User } from './schema';

// export type Variables = {
// me: User;
// };

declare module 'hono' {
// interface ContextVariableMap extends Variables {}
interface ContextVariableMap {
me: User;
}
}

export {};
The same error happens from the React project.
Nico
Nico7mo ago
I have to use screenshots on not on my computer right now. But add this is no different from using ContextVariableMap Which means this is doing nothing
lessquo
lessquoOP7mo ago
If I remove the ContextVariableMap declaration, and remain const app = new Hono<{ Variables: Variables }>();, typescript can't recognize it. ofc I can do this as well:
import { Hono } from 'hono';
import { Variables } from '../hono';

export const users = new Hono<{ Variables: Variables }>().get('/me', c => c.json(c.var.me));
import { Hono } from 'hono';
import { Variables } from '../hono';

export const users = new Hono<{ Variables: Variables }>().get('/me', c => c.json(c.var.me));
but this way, I have to add the type to all my route files
Nico
Nico7mo ago
I’m not sure what’s going on here if you take at look at my example project you’ll see how I’ve declared it and it has no issues. I don’t have to use type generics on each instance of Hono https://github.com/NicoPlyley/hono-auth/blob/main/src/app.d.ts
GitHub
hono-auth/src/app.d.ts at main · NicoPlyley/hono-auth
An example app with authentication using Hono, Drizzle, and D1. Running on CF Workers - NicoPlyley/hono-auth
lessquo
lessquoOP7mo ago
I guess, the difference is that I want to use the type from another package with RPC feature. I configured a monorepo:
my-app/
api
web
my-app/
api
web
package.json in the root directory:
{
"name": "my-app",
"private": true,
"workspaces": [
"api",
"web"
]
}
{
"name": "my-app",
"private": true,
"workspaces": [
"api",
"web"
]
}
The error happens when I try build command bun run build from the web project.
Nico
Nico7mo ago
But you said it goes away when you use type generics/your updated code right?
lessquo
lessquoOP7mo ago
Yes
Nico
Nico7mo ago
Yeah that’s weird because you should be able to use just ContextVariableMap for everything I might have to play around with it with RPC and see
lessquo
lessquoOP7mo ago
I think I can create a reproducible project
Nico
Nico7mo ago
I think I see the issue here the second. On your entry point file to Hono. I bet if you set the context variable map there and not in a separate file it would work. Because of how modules work in typescripts the frontend doesn’t know that file exists
lessquo
lessquoOP7mo ago
You're right. Moving the type declaration part into index.ts file works too! Or, I can just import the type file into the entry file: import './hono.d.ts'; This looks cleaner not sure why export {} doesn't resolve my problem though. Thank you for your help
Nico
Nico7mo ago
Because the tsconfig is react is only going to look for ts modules insides of the react project files not the ones for Hono Now that that’s it’s linked to the code base it know where to find them
lessquo
lessquoOP7mo ago
I see. Maybe, it would be great to add this to the documentation in the Context or RPC page
Nico
Nico7mo ago
Yes I will check tomorrow so see where it can fit in
lessquo
lessquoOP7mo ago
Because I believe the RPC is one of the killer features of Hono. Everyone, including me, wants E2E type safety to reduce unnecessary duplicated code. Again, really appreciated
Want results from more Discord servers?
Add your server