diff --git a/src/types/params.ts b/src/types/params.ts index f2840ee4..4a90efa3 100644 --- a/src/types/params.ts +++ b/src/types/params.ts @@ -11,6 +11,7 @@ export type ParamGetSet = { } 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 diff --git a/src/types/path.ts b/src/types/path.ts index 41b23fca..2ce54c30 100644 --- a/src/types/path.ts +++ b/src/types/path.ts @@ -1,17 +1,37 @@ -import { Param } from '@/types/params' +import { OptionalParam, Param } from '@/types/params' import { ExtractParamsFromPathString } from '@/types/routeMethods' -export type PathParamsParameter = { +export type PathParamsParameter = { [K in keyof ExtractParamsFromPathString]?: Param } export type PathParams< TPath extends string = any, - TParams extends PathParamsParameter = any + TParams extends PathParamsParameter = {} > = { - [K in keyof ExtractParamsFromPathString]: TParams[K] extends Param ? [TParams[K]] : [StringConstructor] + [K in keyof ExtractParamsFromPathString]: ExtractParamsFromPathString[K] extends unknown[] + ? MapOverloadedParam[K], TParams[K]> + : [] } +type ReplaceStringWithConstructor = { + [K in keyof T]: T[K] extends string + ? StringConstructor + : T[K] extends string | undefined + ? StringConstructor | undefined + : T[K] +} + +type MapOverloadedParam = ReplaceStringWithConstructor extends [infer First, ...infer Rest] + ? [CheckOverloadedParam, ...MapOverloadedParam] + : [] + +type CheckOverloadedParam = TOverload extends Param + ? TTarget extends Param + ? TOverload + : TOverload | undefined + : TTarget + export type Path< T extends string = any, P extends PathParams = any diff --git a/src/utilities/path.ts b/src/utilities/path.ts index 4245b4ec..bcb31d11 100644 --- a/src/utilities/path.ts +++ b/src/utilities/path.ts @@ -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

>(params: P, param: string): Param { +function getParam

>(params: P, param: string): Param { return params[param] ?? String }