diff --git a/deno_dist/types.ts b/deno_dist/types.ts index 00b91fb4..d2f9d8d1 100644 --- a/deno_dist/types.ts +++ b/deno_dist/types.ts @@ -1627,7 +1627,9 @@ type ExtractParams = string extends Path ? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string } : Path extends `${infer Start}:${infer Param}` ? { [K in Param]: string } - : {} + : never + +type FlattenIfIntersect = T extends infer O ? { [K in keyof O]: O[K] } : never export type MergeSchemaPath = { [P in keyof OrigSchema as MergePath]: { @@ -1636,8 +1638,10 @@ export type MergeSchemaPath = output: infer Output } ? { - input: Input extends { param: infer Params } - ? { param: Params & ExtractParams } + input: Input extends { param: infer _ } + ? ExtractParams extends never + ? Input + : FlattenIfIntersect }> : RemoveBlankRecord> extends never ? Input : Input & { param: ExtractParams } @@ -1648,6 +1652,8 @@ export type MergeSchemaPath = } export type AddParam = ParamKeys

extends never + ? I + : I extends { param: infer _ } ? I : I & { param: UnionToIntersection>> } diff --git a/src/types.test.ts b/src/types.test.ts index 3103f510..8533f836 100644 --- a/src/types.test.ts +++ b/src/types.test.ts @@ -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> + }) +}) + +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> + }) +}) + +describe('MergePath', () => { + it('Should merge paths correctly', () => { type path1 = MergePath<'/api', '/book'> type verify1 = Expect> type path2 = MergePath<'/api/', '/book'> @@ -486,8 +536,10 @@ describe('merge path', () => { type path4 = MergePath<'/api', '/'> type verify4 = Expect> }) +}) - 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> }) - 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: {} } diff --git a/src/types.ts b/src/types.ts index 7bb1cd92..18d5debb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1627,7 +1627,9 @@ type ExtractParams = string extends Path ? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string } : Path extends `${infer Start}:${infer Param}` ? { [K in Param]: string } - : {} + : never + +type FlattenIfIntersect = T extends infer O ? { [K in keyof O]: O[K] } : never export type MergeSchemaPath = { [P in keyof OrigSchema as MergePath]: { @@ -1636,8 +1638,10 @@ export type MergeSchemaPath = output: infer Output } ? { - input: Input extends { param: infer Params } - ? { param: Params & ExtractParams } + input: Input extends { param: infer _ } + ? ExtractParams extends never + ? Input + : FlattenIfIntersect }> : RemoveBlankRecord> extends never ? Input : Input & { param: ExtractParams } @@ -1648,6 +1652,8 @@ export type MergeSchemaPath = } export type AddParam = ParamKeys

extends never + ? I + : I extends { param: infer _ } ? I : I & { param: UnionToIntersection>> }