Last active
January 7, 2019 22:43
-
-
Save freddi301/bfa17b28621032ed493793cd30d4b0da to your computer and use it in GitHub Desktop.
grapql in typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type DataTypeUnion = ObjectType<any> | ArrayType<any> | PrimitiveTypeUnion; | |
| type PrimitiveTypeUnion = typeof string | typeof number | typeof boolean; | |
| interface QueryType< | |
| Params extends { [key: string]: PrimitiveTypeUnion }, | |
| T extends DataTypeUnion | |
| > { | |
| kind: "query"; | |
| params: Params; | |
| result: T; | |
| selector: [{ [K in keyof Params]: Params["type"] }, T["selector"][0]]; | |
| } | |
| function query< | |
| P extends { [key: string]: PrimitiveTypeUnion }, | |
| T extends DataTypeUnion | |
| >(params: P, result: T): QueryType<P, T> { | |
| return { | |
| kind: "query", | |
| params, | |
| result, | |
| selector: null as any, | |
| }; | |
| } | |
| interface ObjectType< | |
| O extends Record<string, QueryType<any, any> | DataTypeUnion> | |
| > { | |
| kind: "object"; | |
| map: O; | |
| selector: [ | |
| (h: ObjectSelectorHelpers<O>) => Record<string, FieldSelector<O, keyof O>> | |
| ]; | |
| } | |
| function object<O extends Record<string, QueryType<any, any> | DataTypeUnion>>( | |
| map: O, | |
| ): ObjectType<O> { | |
| return { | |
| kind: "object", | |
| map, | |
| selector: null as any, | |
| }; | |
| } | |
| interface FieldSelector< | |
| O extends Record<string, QueryType<any, any> | DataTypeUnion>, | |
| K extends keyof O | |
| > { | |
| key: K; | |
| selector: O[K]["selector"]; | |
| } | |
| type ObjectSelectorHelpers< | |
| O extends Record<string, QueryType<any, any> | DataTypeUnion> | |
| > = { | |
| [K in keyof O]: O[K]["selector"] extends [] | |
| ? FieldSelector<O, K> | |
| : (...args: O[K]["selector"]) => FieldSelector<O, K> | |
| }; | |
| interface ArrayType<T extends DataTypeUnion> { | |
| kind: "array"; | |
| item: T; | |
| selector: T["selector"]; | |
| } | |
| function array<T extends DataTypeUnion>(item: T): ArrayType<T> { | |
| return { | |
| kind: "array", | |
| item, | |
| selector: item.selector, | |
| }; | |
| } | |
| interface PrimitiveType<T, Kind extends string> { | |
| kind: Kind; | |
| selector: []; | |
| type: T; | |
| } | |
| function makePrimitiveType<T, Kind extends string>( | |
| kind: Kind, | |
| ): PrimitiveType<T, Kind> { | |
| return { | |
| kind, | |
| selector: [], | |
| type: null as any, | |
| }; | |
| } | |
| const string = makePrimitiveType<string, "string">("string"); | |
| const number = makePrimitiveType<number, "number">("number"); | |
| const boolean = makePrimitiveType<boolean, "boolean">("boolean"); | |
| const Person = object({ | |
| name: string, | |
| age: number, | |
| }); | |
| const u: typeof Person.selector = [ | |
| ({ name, age }) => ({ | |
| x: name, | |
| age, | |
| }), | |
| ]; | |
| const School = object({ | |
| teachers: array(Person), | |
| kids: array(Person), | |
| director: Person, | |
| kid: query({ id: number }, Person), | |
| }); | |
| const u2: typeof School.selector = [ | |
| ({ director, teachers, kids, kid }) => ({ | |
| others: kids(({ name }) => ({ name })), | |
| me: kid({ id: 42 }, ({ name, age }) => ({ name, power: age })), | |
| devils: teachers(({ age }) => ({ ugliness: age })), | |
| god: director(({ age }) => ({ universeAge: age })), | |
| }), | |
| ]; | |
| // TODO: serialize selector | |
| // TODO: deserialize selector | |
| // TODO: validate | |
| // TODO: create resolver |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment