Skip to content

Instantly share code, notes, and snippets.

@prmichaelsen
Created February 11, 2019 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prmichaelsen/b78123eeb6873a243e956330b544aaed to your computer and use it in GitHub Desktop.
Save prmichaelsen/b78123eeb6873a243e956330b544aaed to your computer and use it in GitHub Desktop.
neat trick for typing an object transform function
/**
this lets you type a function that transforms a map
from a map with KV such that typeof V is some type A<T>
to a a map with KV such that typeof V is some type B<T>
In this case, we go from DataRequest<T> to ISubscription<T>
*/
class Definition<T> {}
interface DataRequest<T> {
def: Definition<T>;
}
interface ISubscription<T> {
def: Definition<T>;
}
function transform<
TRequests
>(requests: TRequests): ({ [P in keyof TRequests]: ISubscription<ExtractType<TRequests[P]>> })
{
return requests as any;
}
interface Project {};
interface Milestone {};
const ProjectDefinition = new Definition<Project>();
const MilestoneDefinition = new Definition<Milestone>();
const projectRequest: DataRequest<Project> = { def: ProjectDefinition };
const milestoneRequest: DataRequest<Milestone> = { def: MilestoneDefinition };
type projectRequestType = ExtractType<typeof projectRequest>;
const subs = transform({ projectRequest, milestoneRequest });
type ExtractType<T> = T extends DataRequest<infer TEntity> ? TEntity : never
type Mapped<T> = ({ [P in keyof T]: ISubscription<ExtractType<T[P]>> });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment