0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-21 18:18:57 +01:00

fix(types): infer path when chaining after use (#3087)

This commit is contained in:
Yusuke Wada 2024-07-04 16:38:40 +09:00 committed by GitHub
parent 1e3e58bb45
commit 7ba58664e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 582 additions and 0 deletions

View File

@ -1838,3 +1838,390 @@ describe('Env types with `use` middleware - test only types', () => {
})
})
})
describe('Env types and a path type with `app.use(path, handler...)` - test only types', () => {
it('Should not throw a type error', () => {
type Env = {
Variables: {
foo: string
}
}
// app.use(path, handler)
new Hono<Env>()
.use('/:id', async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
})
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x2)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x3)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x4)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x5)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x6)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x7)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x8)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x9)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
// app.use(path, handler x10)
new Hono<Env>()
.use(
'/:id',
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
},
async (c, next) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
await next()
}
)
.get((c) => {
expectTypeOf(c.var.foo).toEqualTypeOf<string>()
expectTypeOf(c.req.param('id')).toEqualTypeOf<string>()
return c.json(0)
})
})
})

View File

@ -701,6 +701,16 @@ export interface MiddlewareHandlerInterface<
...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]
): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S, BasePath>
// app.get(path, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E
>(
path: P,
handler: MiddlewareHandler<E2, MergedPath>
): Hono<IntersectNonAnyTypes<[E, E2]>, ChangePathOfSchema<S, MergedPath>, BasePath>
// app.use(handler x3)
<
E2 extends Env = E,
@ -711,6 +721,17 @@ export interface MiddlewareHandlerInterface<
...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S, BasePath>
// app.get(path, handler x2)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = IntersectNonAnyTypes<[E, E2]>
>(
path: P,
...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]
): Hono<IntersectNonAnyTypes<[E, E2, E3]>, ChangePathOfSchema<S, MergedPath>, BasePath>
// app.use(handler x4)
<
E2 extends Env = E,
@ -727,6 +748,18 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S, BasePath>
// app.get(path, handler x3)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>
>(
path: P,
...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, ChangePathOfSchema<S, MergedPath>, BasePath>
// app.use(handler x5)
<
E2 extends Env = E,
@ -745,6 +778,24 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S, BasePath>
// app.get(path, handler x4)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, ChangePathOfSchema<S, MergedPath>, BasePath>
// app.use(handler x6)
<
E2 extends Env = E,
@ -765,6 +816,30 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S, BasePath>
// app.get(path, handler x5)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>
]
): Hono<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
ChangePathOfSchema<S, MergedPath>,
BasePath
>
// app.use(handler x7)
<
E2 extends Env = E,
@ -787,6 +862,32 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S, BasePath>
// app.get(path, handler x6)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>
]
): Hono<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
ChangePathOfSchema<S, MergedPath>,
BasePath
>
// app.use(handler x8)
<
E2 extends Env = E,
@ -811,6 +912,34 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S, BasePath>
// app.get(path, handler x7)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>
]
): Hono<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
ChangePathOfSchema<S, MergedPath>,
BasePath
>
// app.use(handler x9)
<
E2 extends Env = E,
@ -837,6 +966,36 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S, BasePath>
// app.get(path, handler x8)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = E,
E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>
]
): Hono<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
ChangePathOfSchema<S, MergedPath>,
BasePath
>
// app.use(handler x10)
<
E2 extends Env = E,
@ -865,6 +1024,38 @@ export interface MiddlewareHandlerInterface<
]
): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S, BasePath>
// app.get(path, handler x9)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
E2 extends Env = E,
E3 extends Env = E,
E4 extends Env = E,
E5 extends Env = E,
E6 extends Env = E,
E7 extends Env = E,
E8 extends Env = E,
E9 extends Env = E,
E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>
>(
path: P,
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>,
MiddlewareHandler<E10, P>
]
): Hono<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
ChangePathOfSchema<S, MergedPath>,
BasePath
>
//// app.use(path, ...handlers[])
<P extends string, E2 extends Env = E>(
path: P,
@ -1612,6 +1803,10 @@ export type Schema = {
}
}
type ChangePathOfSchema<S extends Schema, Path extends string> = keyof S extends never
? { [K in Path]: never }
: { [K in keyof S as Path]: S[K] }
export type Endpoint = {
input: Partial<ValidationTargets>
output: any