Skip to content

Commit

Permalink
preserving tuples and optionality of params
Browse files Browse the repository at this point in the history
  • Loading branch information
stackoverfloweth committed Dec 16, 2023
1 parent b05df8b commit 6699adb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/types/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type ParamGetSet<T = any> = {
}

export type Param = ParamGetter | ParamGetSet | RegExp | BooleanConstructor | NumberConstructor
export type OptionalParam = Param | undefined

export function isParamGetter(value: Param): value is ParamGetter {
return typeof value === 'function' && value !== Boolean && value !== Number
Expand Down
28 changes: 24 additions & 4 deletions src/types/path.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import { Param } from '@/types/params'
import { OptionalParam, Param } from '@/types/params'
import { ExtractParamsFromPathString } from '@/types/routeMethods'

export type PathParamsParameter<T extends string> = {
export type PathParamsParameter<T extends string = any> = {
[K in keyof ExtractParamsFromPathString<T>]?: Param
}

export type PathParams<
TPath extends string = any,
TParams extends PathParamsParameter<TPath> = any
TParams extends PathParamsParameter<TPath> = {}
> = {
[K in keyof ExtractParamsFromPathString<TPath>]: TParams[K] extends Param ? [TParams[K]] : [StringConstructor]
[K in keyof ExtractParamsFromPathString<TPath>]: ExtractParamsFromPathString<TPath>[K] extends unknown[]
? MapOverloadedParam<ExtractParamsFromPathString<TPath>[K], TParams[K]>
: []
}

type ReplaceStringWithConstructor<T> = {
[K in keyof T]: T[K] extends string
? StringConstructor
: T[K] extends string | undefined
? StringConstructor | undefined
: T[K]
}

type MapOverloadedParam<TParams extends unknown[], TOverload extends OptionalParam> = ReplaceStringWithConstructor<TParams> extends [infer First, ...infer Rest]
? [CheckOverloadedParam<First, TOverload>, ...MapOverloadedParam<Rest, TOverload>]
: []

type CheckOverloadedParam<TTarget, TOverload> = TOverload extends Param
? TTarget extends Param
? TOverload
: TOverload | undefined
: TTarget

export type Path<
T extends string = any,
P extends PathParams<T> = any
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/path.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { optional, Param, Identity, Path, PathParamsParameter, PathParams } from '@/types'
import { optional, Param, Identity, Path, PathParamsParameter, PathParams, OptionalParam } from '@/types'
import { mergeParams } from '@/utilities'

function getParam<P extends Record<string, Param | undefined>>(params: P, param: string): Param {
function getParam<P extends Record<string, OptionalParam>>(params: P, param: string): Param {
return params[param] ?? String
}

Expand Down

0 comments on commit 6699adb

Please sign in to comment.