Skip to content

Instantly share code, notes, and snippets.

@ksaldana1
Last active June 25, 2018 23:15
Show Gist options
  • Save ksaldana1/ceda997d9ae8ca14f78aca3d17857f0c to your computer and use it in GitHub Desktop.
Save ksaldana1/ceda997d9ae8ca14f78aca3d17857f0c to your computer and use it in GitHub Desktop.
#25157 Repro - File 1
// Interface returned by our RouteCreator function
export interface Route<Parts extends PathPart<any>> {
template(): string;
create(params: UnionToIntersection<OnlyParams<Parts>>): string;
}
export type PathPart<T extends string> = string | PathParam<T>;
export function param<T extends string>(t: T): PathParam<T> {
return { param: t };
}
export interface PathParam<T extends string> {
param: T;
}
// Pluck only the parameter types from a Route
export type OnlyParams<T> = T extends PathParam<infer K> ? Record<K, string> : {};
// Given the parameters of a route I want an object of { paramName: string }
// e.g. for const Route = route(['logbook', param('logbookId'), param('otherId')]);
// RouteParams<Route> = { logbookId: string, otherId: string }
export type RouteParams<T extends Route<any>> = T extends Route<infer Parts>
? UnionToIntersection<OnlyParams<Parts>>
: never;
// Type Utils
export type GetKeys<U> = U extends Record<infer K, any> ? K : never;
export type UnionToIntersection<U extends object> = {
[K in GetKeys<U>]: U extends Record<K, infer T> ? T : never
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment