Skip to content

Instantly share code, notes, and snippets.

@baetheus
Created March 21, 2021 02:37
Show Gist options
  • Select an option

  • Save baetheus/e595ae2e8459915f945143d652bfe737 to your computer and use it in GitHub Desktop.

Select an option

Save baetheus/e595ae2e8459915f945143d652bfe737 to your computer and use it in GitHub Desktop.
Minimal Schemable Example
/*******************************************************************************
* Kinds Type
* @description A registry for Kind URIS with their substitution strategies.
* Note that the idiomatic replacement type for kinds uses _0 as the inner-
* most hole for Functor and Chain. Thus Either<L, R> should use the hole
* order of Either<_1, _0>. This is reflected in the replacement strategies
* used in type_classes.ts
******************************************************************************/
export interface Kinds<A, B, C, D> {
["Test"]: Test<A>;
}
/*******************************************************************************
* URIS Type
* @description A union of all visible Kinds
******************************************************************************/
export type URIS = keyof Kinds<any, any, any, any>;
/*******************************************************************************
* Kind Type
* @description A lookup type used to specify a Kind substitution
******************************************************************************/
export type Kind<URI extends URIS, A, B, C, D> = Kinds<A, B, C, D>[URI];
// Test
export type StructSchemable<URI extends URIS> = {
readonly struct: <A, B = never, C = never, D = never>(
properties: { [K in keyof A]: Kind<URI, A[K], B, C, D> },
) => Kind<URI, { [K in keyof A]: A[K] }, B, C, D>;
};
export type Schemable<URI extends URIS> = StructSchemable<URI>;
type Test<A> = (r: unknown) => A;
type TypeOf<T> = T extends Test<infer A> ? A : never;
const { struct }: StructSchemable<"Test"> = {
struct: (properties) =>
(i) => {
let out: Record<string, unknown> = {};
for (const key in properties) {
const t = properties[key];
const o = t(i);
out[key] = o;
}
return out as {
[K in keyof typeof properties]: TypeOf<(typeof properties)[K]>;
};
},
};
const number: Test<number> = (i: unknown): number => 1;
const a1 = struct({ one: number });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment