Open Luzefiru opened 4 months ago
Hi @Luzefiru
Thanks for the issue, and sorry for the delayed response!
Now, we have to consider matters such as ContextVariableMap
or something related to it.
Your suggestion is good. But there is another option: https://github.com/honojs/hono/issues/2249, although ContextBindingMap
is different from ContextVariableMap
. This issue is said to discourage using ContextVariableMap
. I also think it's not good that it pollutes global types.
Anyway, I'll think about this issue deeply.
This issue is said to discourage using
ContextVariableMap
. I also think it's not good that it pollutes global types.
I agree on this part, I guess making another globally scoped type will create more issues and shouldn't be done. For future reference, should we simply just type the context argument as Context<Env>
for controller functions that do not have access to the Hono app
? Like so:
function handleRouteWithEnvGeneric(c: Context<Env>) {
c.get("foo"); // this works, Get <"client">(key: "client") => number
c.var.foo; // this works, (property) foo: string
c.get("bar"); // works now, Get <"bar">(key: "bar") => number (+1 overload)
c.var.bar; // works now, (property) bar: number
c.env.MY_SECRET; // (property) MY_SECRET: string
}
I understand that it's something that is advised against in the Best Practices documentation, but my route files are getting too big. I was hoping to implement the pattern without having to always type the c: Context<Env>
argument.
Is there a better way to do this? Thank you very much for your response.
declare module 'hono' {
interface ContextVariableMap {
}
interface Env {
Bindings: {
ip: SocketAddress
}
}
}
This seems to be working
What is the feature you are proposing?
Suggestion
There is no simple way to type environment bindings (like for Cloudflare Worker secrets) and you'll need to pass a constructor like this
const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()
to your Hono apps.The problem occurs when you want to use
app.route
and create multiple Hono apps with the same variables or bindings.If only there was a
ContextBindingMap
, similar toContextVariableMap
, to declare a module interface to write any global bindings there, then you can simply type your context like(c: Context)
in a route to be able to get types in yourc.env
orenv(c)
Bindings.A simple example to use this potential feature is like so:
By extension of this feature being implemented, the documentation website should also be updated to reflect the new API.
Status Quo
Currently, in the Hono Documentation Website, there is a section on adding global types to your context's
c.var
interface viaContextVariableMap
.Once you make a route handler with the
('/path', (c: Context) => ...)
arguments, you can accessc.var
variables without having to make anEnv
generic for the Context likeContext<Env>
.Here are the sections that talk about it typing the context
c.var
orc.env
properties in yournew Hono()
instance usingtype Bindings
andtype Variables
:Exhibit A:
/helpers/factory
There is documentation on how to use the
Env
generic using thecreateFactory
helper.Exhibit B:
/api/context
The Generics documentation shows that we can pass our
Variables
andBindings
to ournew Hono()
constructor. This documentation is consistent with Exhibit A, showcasing the fact that a factory is just saving the config of the Hono instance so that we can passtype Variables
to the constructors to type ourc.var
properties.There's also similar usage in the
set() / get() docs
.