Skip to content

Commit 37c3809

Browse files
authored
fix(types): fix app.on method array type inference (#4578)
1 parent fe278e9 commit 37c3809

File tree

2 files changed

+73
-38
lines changed

2 files changed

+73
-38
lines changed

src/types.test.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,35 @@ describe('OnHandlerInterface', () => {
320320
type verify = Expect<Equal<Expected, Actual>>
321321
})
322322

323+
test('app.on(method[], path, middleware, handler)', () => {
324+
const middleware: MiddlewareHandler<{ Variables: { foo: string } }> = async () => {}
325+
const route = app.on(['GET', 'POST'], '/multi-method', middleware, (c) => {
326+
return c.json({ success: true })
327+
})
328+
type Actual = ExtractSchema<typeof route>
329+
type Expected = {
330+
'/multi-method': {
331+
$get: {
332+
input: {}
333+
output: {
334+
success: true
335+
}
336+
outputFormat: 'json'
337+
status: ContentfulStatusCode
338+
}
339+
$post: {
340+
input: {}
341+
output: {
342+
success: true
343+
}
344+
outputFormat: 'json'
345+
status: ContentfulStatusCode
346+
}
347+
}
348+
}
349+
type verify = Expect<Equal<Expected, Actual>>
350+
})
351+
323352
test('app.on(method, path[], middleware, handler) should not throw a type error', () => {
324353
const middleware: MiddlewareHandler<{ Variables: { foo: string } }> = async () => {}
325354
app.on('GET', ['/a', '/b'], middleware, (c) => {
@@ -339,7 +368,7 @@ describe('OnHandlerInterface', () => {
339368
type Actual = ExtractSchema<typeof route>
340369
type Expected = {
341370
'/a': {
342-
[x: `$${Lowercase<string>}`]: {
371+
$get: {
343372
input: {}
344373
output: {
345374
first: true
@@ -349,7 +378,7 @@ describe('OnHandlerInterface', () => {
349378
}
350379
}
351380
'/b': {
352-
[x: `$${Lowercase<string>}`]: {
381+
$get: {
353382
input: {}
354383
output: {
355384
first: true

src/types.ts

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,26 +1815,26 @@ export interface OnHandlerInterface<
18151815

18161816
// app.on(method[], path, handler)
18171817
<
1818-
Ms extends string[],
1818+
M extends string,
18191819
P extends string,
18201820
MergedPath extends MergePath<BasePath, P>,
18211821
R extends HandlerResponse<any> = any,
18221822
I extends Input = BlankInput,
18231823
E2 extends Env = E,
18241824
>(
1825-
methods: Ms,
1825+
methods: M[],
18261826
path: P,
18271827
handler: H<E2, MergedPath, I, R>
18281828
): HonoBase<
18291829
IntersectNonAnyTypes<[E, E2]>,
1830-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
1830+
S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
18311831
BasePath,
18321832
MergePath<BasePath, P>
18331833
>
18341834

18351835
// app.on(method[], path, handler x2)
18361836
<
1837-
Ms extends string[],
1837+
M extends string,
18381838
P extends string,
18391839
MergedPath extends MergePath<BasePath, P>,
18401840
R extends HandlerResponse<any> = any,
@@ -1843,19 +1843,19 @@ export interface OnHandlerInterface<
18431843
E2 extends Env = E,
18441844
E3 extends Env = IntersectNonAnyTypes<[E, E2]>,
18451845
>(
1846-
methods: Ms,
1846+
methods: M[],
18471847
path: P,
18481848
...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
18491849
): HonoBase<
18501850
IntersectNonAnyTypes<[E, E2, E3]>,
1851-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I2, MergeTypedResponse<R>>,
1851+
S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>,
18521852
BasePath,
18531853
MergePath<BasePath, P>
18541854
>
18551855

18561856
// app.on(method[], path, handler x3)
18571857
<
1858-
Ms extends string[],
1858+
M extends string,
18591859
P extends string,
18601860
MergedPath extends MergePath<BasePath, P>,
18611861
R extends HandlerResponse<any> = any,
@@ -1866,19 +1866,19 @@ export interface OnHandlerInterface<
18661866
E3 extends Env = IntersectNonAnyTypes<[E, E2]>,
18671867
E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>,
18681868
>(
1869-
methods: Ms,
1869+
methods: M[],
18701870
path: P,
18711871
...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]
18721872
): HonoBase<
18731873
IntersectNonAnyTypes<[E, E2, E3, E4]>,
1874-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I3, MergeTypedResponse<R>>,
1874+
S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>,
18751875
BasePath,
18761876
MergePath<BasePath, P>
18771877
>
18781878

18791879
// app.on(method[], path, handler x4)
18801880
<
1881-
Ms extends string[],
1881+
M extends string,
18821882
P extends string,
18831883
MergedPath extends MergePath<BasePath, P>,
18841884
R extends HandlerResponse<any> = any,
@@ -1891,7 +1891,7 @@ export interface OnHandlerInterface<
18911891
E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>,
18921892
E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>,
18931893
>(
1894-
methods: Ms,
1894+
methods: M[],
18951895
path: P,
18961896
...handlers: [
18971897
H<E2, MergedPath, I>,
@@ -1901,14 +1901,14 @@ export interface OnHandlerInterface<
19011901
]
19021902
): HonoBase<
19031903
IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
1904-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I4, MergeTypedResponse<R>>,
1904+
S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R>>,
19051905
BasePath,
19061906
MergePath<BasePath, P>
19071907
>
19081908

19091909
// app.on(method[], path, handler x5)
19101910
<
1911-
Ms extends string[],
1911+
M extends string,
19121912
P extends string,
19131913
MergedPath extends MergePath<BasePath, P>,
19141914
R extends HandlerResponse<any> = any,
@@ -1923,7 +1923,7 @@ export interface OnHandlerInterface<
19231923
E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>,
19241924
E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
19251925
>(
1926-
methods: Ms,
1926+
methods: M[],
19271927
path: P,
19281928
...handlers: [
19291929
H<E2, MergedPath, I>,
@@ -1934,14 +1934,14 @@ export interface OnHandlerInterface<
19341934
]
19351935
): HonoBase<
19361936
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
1937-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I5, MergeTypedResponse<R>>,
1937+
S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>,
19381938
BasePath,
19391939
MergePath<BasePath, P>
19401940
>
19411941

19421942
// app.on(method[], path, handler x6)
19431943
<
1944-
Ms extends string[],
1944+
M extends string,
19451945
P extends string,
19461946
MergedPath extends MergePath<BasePath, P>,
19471947
R extends HandlerResponse<any> = any,
@@ -1958,7 +1958,7 @@ export interface OnHandlerInterface<
19581958
E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
19591959
E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
19601960
>(
1961-
methods: Ms,
1961+
methods: M[],
19621962
path: P,
19631963
...handlers: [
19641964
H<E2, MergedPath, I>,
@@ -1970,14 +1970,14 @@ export interface OnHandlerInterface<
19701970
]
19711971
): HonoBase<
19721972
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
1973-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I6, MergeTypedResponse<R>>,
1973+
S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>,
19741974
BasePath,
19751975
MergePath<BasePath, P>
19761976
>
19771977

19781978
// app.on(method[], path, handler x7)
19791979
<
1980-
Ms extends string[],
1980+
M extends string,
19811981
P extends string,
19821982
MergedPath extends MergePath<BasePath, P>,
19831983
R extends HandlerResponse<any> = any,
@@ -1996,7 +1996,7 @@ export interface OnHandlerInterface<
19961996
E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
19971997
E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
19981998
>(
1999-
methods: Ms,
1999+
methods: M[],
20002000
path: P,
20012001
...handlers: [
20022002
H<E2, MergedPath, I>,
@@ -2009,14 +2009,14 @@ export interface OnHandlerInterface<
20092009
]
20102010
): HonoBase<
20112011
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
2012-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I7, MergeTypedResponse<R>>,
2012+
S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>,
20132013
BasePath,
20142014
MergePath<BasePath, P>
20152015
>
20162016

20172017
// app.on(method[], path, handler x8)
20182018
<
2019-
Ms extends string[],
2019+
M extends string,
20202020
P extends string,
20212021
MergedPath extends MergePath<BasePath, P>,
20222022
R extends HandlerResponse<any> = any,
@@ -2037,7 +2037,7 @@ export interface OnHandlerInterface<
20372037
E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
20382038
E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
20392039
>(
2040-
methods: Ms,
2040+
methods: M[],
20412041
path: P,
20422042
...handlers: [
20432043
H<E2, MergedPath, I>,
@@ -2051,14 +2051,14 @@ export interface OnHandlerInterface<
20512051
]
20522052
): HonoBase<
20532053
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
2054-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I8, MergeTypedResponse<R>>,
2054+
S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>,
20552055
BasePath,
20562056
MergePath<BasePath, P>
20572057
>
20582058

20592059
// app.on(method[], path, handler x9)
20602060
<
2061-
Ms extends string[],
2061+
M extends string,
20622062
P extends string,
20632063
MergedPath extends MergePath<BasePath, P>,
20642064
R extends HandlerResponse<any> = any,
@@ -2081,7 +2081,7 @@ export interface OnHandlerInterface<
20812081
E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
20822082
E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
20832083
>(
2084-
methods: Ms,
2084+
methods: M[],
20852085
path: P,
20862086
...handlers: [
20872087
H<E2, MergedPath, I>,
@@ -2096,14 +2096,14 @@ export interface OnHandlerInterface<
20962096
]
20972097
): HonoBase<
20982098
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
2099-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I9, MergeTypedResponse<HandlerResponse<any>>>,
2099+
S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<HandlerResponse<any>>>,
21002100
BasePath,
21012101
MergePath<BasePath, P>
21022102
>
21032103

21042104
// app.on(method[], path, handler x10)
21052105
<
2106-
Ms extends string[],
2106+
M extends string,
21072107
P extends string,
21082108
MergedPath extends MergePath<BasePath, P>,
21092109
R extends HandlerResponse<any> = any,
@@ -2128,7 +2128,7 @@ export interface OnHandlerInterface<
21282128
E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
21292129
E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
21302130
>(
2131-
methods: Ms,
2131+
methods: M[],
21322132
path: P,
21332133
...handlers: [
21342134
H<E2, MergedPath, I>,
@@ -2144,36 +2144,42 @@ export interface OnHandlerInterface<
21442144
]
21452145
): HonoBase<
21462146
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
2147-
S & ToSchema<Ms[number], MergePath<BasePath, P>, I10, MergeTypedResponse<HandlerResponse<any>>>,
2147+
S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<HandlerResponse<any>>>,
21482148
BasePath,
21492149
MergePath<BasePath, P>
21502150
>
21512151

2152-
// app.on(method[], path, ...handler)
2153-
<P extends string, R extends HandlerResponse<any> = any, I extends Input = BlankInput>(
2154-
methods: string[],
2152+
// app.on(method[], path, ...handlers[])
2153+
<
2154+
M extends string,
2155+
P extends string,
2156+
R extends HandlerResponse<any> = any,
2157+
I extends Input = BlankInput,
2158+
>(
2159+
methods: M[],
21552160
path: P,
21562161
...handlers: [H<E, MergePath<BasePath, P>, I, R>, ...H<E, MergePath<BasePath, P>, I, R>[]]
21572162
): HonoBase<
21582163
E,
2159-
S & ToSchema<string, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
2164+
S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>,
21602165
BasePath,
21612166
MergePath<BasePath, P>
21622167
>
21632168

21642169
// app.on(method | method[], path[], ...handlers[])
21652170
<
2171+
M extends string,
21662172
const Ps extends string[],
21672173
I extends Input = BlankInput,
21682174
R extends HandlerResponse<any> = any,
21692175
E2 extends Env = E,
21702176
>(
2171-
methods: string | string[],
2177+
methods: M | M[],
21722178
paths: Ps,
21732179
...handlers: H<E2, MergePath<BasePath, Ps[number]>, I, R>[]
21742180
): HonoBase<
21752181
E,
2176-
S & ToSchema<string, MergePath<BasePath, Ps[number]>, I, MergeTypedResponse<R>>,
2182+
S & ToSchema<M, MergePath<BasePath, Ps[number]>, I, MergeTypedResponse<R>>,
21772183
BasePath,
21782184
Ps extends [...string[], infer LastPath extends string] ? MergePath<BasePath, LastPath> : never
21792185
>

0 commit comments

Comments
 (0)