Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(types): replace intersection with union to get better perf #3443

Merged
merged 5 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/hono-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends string =
>(
path: SubPath,
app: Hono<SubEnv, SubSchema, SubBasePath>
): Hono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath> {
): Hono<
E,
ExcludeEmptyObject<MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> | S>,
BasePath
> {
const subApp = this.basePath(path)
app.routes.map((r) => {
let handler
Expand Down Expand Up @@ -519,5 +523,6 @@ class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends string =
})
}
}
export type ExcludeEmptyObject<T> = T extends {} ? ({} extends T ? never : T) : T
m-shaka marked this conversation as resolved.
Show resolved Hide resolved

export { Hono as HonoBase }
36 changes: 16 additions & 20 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1817,24 +1817,21 @@ type ExtractParams<Path extends string> = string extends Path

type FlattenIfIntersect<T> = T extends infer O ? { [K in keyof O]: O[K] } : never

export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = Simplify<{
[P in keyof OrigSchema as MergePath<SubPath, P & string>]: {
[M in keyof OrigSchema[P]]: MergeEndpointParamsWithPath<OrigSchema[P][M], SubPath>
}
}>

type MergeEndpointParamsWithPath<T, SubPath extends string> = T extends {
input: infer Input
output: infer Output
outputFormat: infer OutputFormat
status: infer Status
export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = {
[P in keyof OrigSchema as MergePath<SubPath, P & string>]: [OrigSchema[P]] extends [
Record<string, Endpoint>
]
? { [M in keyof OrigSchema[P]]: MergeEndpointParamsWithPath<OrigSchema[P][M], SubPath> }
: never
}

type MergeEndpointParamsWithPath<T extends Endpoint, SubPath extends string> = T extends unknown
? {
input: Input extends { param: infer _ }
input: T['input'] extends { param: infer _ }
? ExtractParams<SubPath> extends never
? Input
? T['input']
: FlattenIfIntersect<
Input & {
T['input'] & {
param: {
// Maps extracted keys, stripping braces, to a string-typed record.
[K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}`
Expand All @@ -1844,21 +1841,20 @@ type MergeEndpointParamsWithPath<T, SubPath extends string> = T extends {
}
>
: RemoveBlankRecord<ExtractParams<SubPath>> extends never
? Input
: Input & {
? T['input']
: T['input'] & {
// Maps extracted keys, stripping braces, to a string-typed record.
param: {
[K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}`
? Prefix
: K]: string
}
}
output: Output
outputFormat: OutputFormat
status: Status
output: T['output']
outputFormat: T['outputFormat']
status: T['status']
}
: never

export type AddParam<I, P extends string> = ParamKeys<P> extends never
? I
: I extends { param: infer _ }
Expand Down