mirror of
https://github.com/honojs/hono.git
synced 2024-11-21 18:18:57 +01:00
fix(types): MergeSchemaPath
infer inputs not only params (#2154)
* fix(types): `MergeSchemaPath` infer inputs not only params * denoify * format
This commit is contained in:
parent
97dd369f5e
commit
09845e5e04
@ -1627,7 +1627,9 @@ type ExtractParams<Path extends string> = string extends Path
|
||||
? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string }
|
||||
: Path extends `${infer Start}:${infer Param}`
|
||||
? { [K in Param]: string }
|
||||
: {}
|
||||
: never
|
||||
|
||||
type FlattenIfIntersect<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
|
||||
|
||||
export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = {
|
||||
[P in keyof OrigSchema as MergePath<SubPath, P & string>]: {
|
||||
@ -1636,8 +1638,10 @@ export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> =
|
||||
output: infer Output
|
||||
}
|
||||
? {
|
||||
input: Input extends { param: infer Params }
|
||||
? { param: Params & ExtractParams<SubPath> }
|
||||
input: Input extends { param: infer _ }
|
||||
? ExtractParams<SubPath> extends never
|
||||
? Input
|
||||
: FlattenIfIntersect<Input & { param: ExtractParams<SubPath> }>
|
||||
: RemoveBlankRecord<ExtractParams<SubPath>> extends never
|
||||
? Input
|
||||
: Input & { param: ExtractParams<SubPath> }
|
||||
@ -1648,6 +1652,8 @@ export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> =
|
||||
}
|
||||
|
||||
export type AddParam<I, P extends string> = ParamKeys<P> extends never
|
||||
? I
|
||||
: I extends { param: infer _ }
|
||||
? I
|
||||
: I & { param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>> }
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { createMiddleware } from './helper'
|
||||
import { Hono } from './hono'
|
||||
import { poweredBy } from './middleware/powered-by'
|
||||
import type {
|
||||
AddParam,
|
||||
Env,
|
||||
ExtractSchema,
|
||||
Handler,
|
||||
@ -475,8 +476,57 @@ describe('For HonoRequest', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('merge path', () => {
|
||||
test('MergePath', () => {
|
||||
describe('AddParam', () => {
|
||||
it('Should add params to input correctly', () => {
|
||||
type Actual = AddParam<
|
||||
{
|
||||
param: {
|
||||
id: string
|
||||
}
|
||||
} & {
|
||||
query: {
|
||||
page: string
|
||||
}
|
||||
},
|
||||
'/:id'
|
||||
>
|
||||
type Expected = {
|
||||
query: {
|
||||
page: string
|
||||
}
|
||||
} & {
|
||||
param: {
|
||||
id: string
|
||||
}
|
||||
}
|
||||
type verify = Expect<Equal<Expected, Actual>>
|
||||
})
|
||||
})
|
||||
|
||||
describe('ToSchema', () => {
|
||||
it('Should convert parameters to schema correctly', () => {
|
||||
type Actual = ToSchema<'get', '/:id', { param: { id: string }; query: { page: string } }, {}>
|
||||
type Expected = {
|
||||
'/:id': {
|
||||
$get: {
|
||||
input: {
|
||||
param: {
|
||||
id: string
|
||||
}
|
||||
query: {
|
||||
page: string
|
||||
}
|
||||
}
|
||||
output: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
type verify = Expect<Equal<Expected, Actual>>
|
||||
})
|
||||
})
|
||||
|
||||
describe('MergePath', () => {
|
||||
it('Should merge paths correctly', () => {
|
||||
type path1 = MergePath<'/api', '/book'>
|
||||
type verify1 = Expect<Equal<'/api/book', path1>>
|
||||
type path2 = MergePath<'/api/', '/book'>
|
||||
@ -486,8 +536,10 @@ describe('merge path', () => {
|
||||
type path4 = MergePath<'/api', '/'>
|
||||
type verify4 = Expect<Equal<'/api', path4>>
|
||||
})
|
||||
})
|
||||
|
||||
test('MergeSchemaPath', () => {
|
||||
describe('MergeSchemaPath', () => {
|
||||
it('Should merge schema and sub path correctly', () => {
|
||||
type Sub = ToSchema<
|
||||
'post',
|
||||
'/posts',
|
||||
@ -537,7 +589,7 @@ describe('merge path', () => {
|
||||
type verify = Expect<Equal<Expected, Actual>>
|
||||
})
|
||||
|
||||
test('MergeSchemePath - with params and the subpath does not have params', () => {
|
||||
it('Should merge schema which has params and sub path does not have params', () => {
|
||||
type Actual = MergeSchemaPath<
|
||||
{
|
||||
'/': {
|
||||
@ -546,6 +598,9 @@ describe('merge path', () => {
|
||||
param: {
|
||||
id: string
|
||||
}
|
||||
query: {
|
||||
page: string
|
||||
}
|
||||
}
|
||||
output: {}
|
||||
}
|
||||
@ -560,6 +615,9 @@ describe('merge path', () => {
|
||||
param: {
|
||||
id: string
|
||||
}
|
||||
query: {
|
||||
page: string
|
||||
}
|
||||
}
|
||||
output: {}
|
||||
}
|
||||
|
12
src/types.ts
12
src/types.ts
@ -1627,7 +1627,9 @@ type ExtractParams<Path extends string> = string extends Path
|
||||
? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string }
|
||||
: Path extends `${infer Start}:${infer Param}`
|
||||
? { [K in Param]: string }
|
||||
: {}
|
||||
: never
|
||||
|
||||
type FlattenIfIntersect<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
|
||||
|
||||
export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = {
|
||||
[P in keyof OrigSchema as MergePath<SubPath, P & string>]: {
|
||||
@ -1636,8 +1638,10 @@ export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> =
|
||||
output: infer Output
|
||||
}
|
||||
? {
|
||||
input: Input extends { param: infer Params }
|
||||
? { param: Params & ExtractParams<SubPath> }
|
||||
input: Input extends { param: infer _ }
|
||||
? ExtractParams<SubPath> extends never
|
||||
? Input
|
||||
: FlattenIfIntersect<Input & { param: ExtractParams<SubPath> }>
|
||||
: RemoveBlankRecord<ExtractParams<SubPath>> extends never
|
||||
? Input
|
||||
: Input & { param: ExtractParams<SubPath> }
|
||||
@ -1648,6 +1652,8 @@ export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> =
|
||||
}
|
||||
|
||||
export type AddParam<I, P extends string> = ParamKeys<P> extends never
|
||||
? I
|
||||
: I extends { param: infer _ }
|
||||
? I
|
||||
: I & { param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>> }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user