Skip to content

Commit

Permalink
Merge pull request #1 from alexmccabe/wip/improve-types-further
Browse files Browse the repository at this point in the history
Wip/improve types further
  • Loading branch information
alexmccabe authored Jan 10, 2024
2 parents 2f368ea + 7cd9786 commit 069d9c3
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/js/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type ParameterValue = RawParameterValue | DefaultRoutable;
* A parseable route parameter, either plain or nested inside an object under its binding key.
*/
type Routable<I extends ParameterInfo> = I extends { binding: string }
? { [K in I['binding']]: RawParameterValue } | RawParameterValue
? ({ [K in I['binding']]: RawParameterValue } & Record<string, unknown>) | RawParameterValue
: ParameterValue;

// Uncomment to test:
Expand All @@ -52,6 +52,16 @@ type Routable<I extends ParameterInfo> = I extends { binding: string }
// type B = Routable<{ name: 'foo' }>;
// = RawParameterValue | DefaultRoutable

// Utility types for `KnownRouteParamsObject`:
type PartiallyOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type ArrToObj<I extends readonly ParameterInfo[]> = {
[T in I[number] as T['name']]: T;
};
type OptionalParams<I extends readonly ParameterInfo[]> = Extract<
I[number],
{ optional: true }
>['name'];

/**
* An object containing a special '_query' key to target the query string of a URL.
*/
Expand All @@ -64,10 +74,12 @@ type GenericRouteParamsObject = Record<keyof any, unknown> & HasQueryParam;
/**
* An object of parameters for a specific named route.
*/
type KnownRouteParamsObject<I extends readonly ParameterInfo[]> = {
[T in Extract<I[number], { optional: false }> as T['name']]: Routable<T>;
} & {
[T in Extract<I[number], { optional: true }> as T['name']]?: Routable<T>;
type KnownRouteParamsObject<
TInfo extends readonly ParameterInfo[],
TOptionalKeys extends TInfo[number]['name'] = OptionalParams<TInfo>,
TInfoObj extends Record<string, ParameterInfo> = ArrToObj<TInfo>,
> = {
[K in keyof PartiallyOptional<TInfoObj, TOptionalKeys>]: Routable<TInfoObj[K]>;
} & GenericRouteParamsObject;
// `readonly` allows TypeScript to determine the actual values of all the
// parameter names inside the array, instead of just seeing `string`.
Expand Down Expand Up @@ -117,7 +129,7 @@ type RouteParamsArray<N extends RouteName> = N extends KnownRouteName
/**
* All possible parameter argument shapes for a route.
*/
type RouteParams<N extends RouteName> = ParameterValue | RouteParamsObject<N> | RouteParamsArray<N>;
type RouteParams<N extends RouteName> = RouteParamsObject<N> | RouteParamsArray<N>;

/**
* A route.
Expand Down Expand Up @@ -169,6 +181,12 @@ export default function route<T extends RouteName>(
absolute?: boolean,
config?: Config,
): string;
export default function route<T extends RouteName>(
name: T,
params?: ParameterValue | undefined,
absolute?: boolean,
config?: Config,
): string;
// Called with configuration arguments only - returns a configured Router instance
export default function route(
name: undefined,
Expand Down

0 comments on commit 069d9c3

Please sign in to comment.