Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] How can we use the types in runtime? #470

Open
frank-zsy opened this issue May 14, 2021 · 6 comments
Open

[Question] How can we use the types in runtime? #470

frank-zsy opened this issue May 14, 2021 · 6 comments
Labels
Type: Support Any questions, information, or general needs around the SDK or GitHub APIs
Projects

Comments

@frank-zsy
Copy link

Right now all the types are defined as type so we can use them in program to get the types. But actually I think we can also use the types to generate the GraphQL SQL query string automatically.

So I think if we can define the types as class and use a class instance as the parameter so the underlying program can generate query string from the instance and return the right type as well. Are there any side effects if we use class instead of type to do this?

@ghost ghost added this to Inbox in JS May 14, 2021
@wengzhenjie
Copy link

wengzhenjie commented May 14, 2021

I have the problem!

@gr2m
Copy link
Contributor

gr2m commented May 14, 2021

I don't quite understand what you are suggestion. Do you want to start a PR to show what you mean, and we can discuss there?

@gr2m gr2m added awaiting response Type: Support Any questions, information, or general needs around the SDK or GitHub APIs labels May 14, 2021
@ghost ghost moved this from Inbox to Awaiting response in JS May 14, 2021
@frank-zsy
Copy link
Author

frank-zsy commented May 16, 2021

Thanks for the reply.

I still did not figure it out but I can give a simple example to show what I mean:

class Repository {
  id: number;
  name: string;
  issue: {
    number: number;
    body: string;
    comment: {
      id: number;
      body: string;
    }
  };
}

type SchemaType<T> = { [ P in keyof T ]?: T[P] extends object ? SchemaType<T[P]> : true };
type ResultType<T, G = SchemaType<T>> = { [ P in (keyof T & keyof G) ]: G[P] extends object ? ResultType<T[P], G[P]> : T[P] };

function getPartialData<T>(_type: new () => T, schema: SchemaType<T>): ResultType<T, typeof schema> {
  const genData = (obj: any) => {
    const res: any = {};
    for (const k in obj) {
      if (typeof obj[k] === 'object') {
        res[k] = genData(obj[k]);
      } else {
        res[k] = 1;
      }
    }
    return res;
  };
  return genData(schema);   // generate data, can generate GraphQL query by schema and return result.
}

const schema: SchemaType<Repository> = {
  id: true,
  issue: {
    number: true,
    comment: {
      id: true,
    }
  },
};

console.log(getPartialData(Repository, schema));  // { id: 1, issue: { number: 1, comment: { id: 1 } } }

In above code, we can query the repository data from the getPartialData function with Repository class and a schema config. And the constraints are:

  • The schema config structure we can pass into the function is constrained by the first parameter which is the data type we request. It is defined by SchemaType so we can not pass in an invalid structure and the values should only be true.
  • The returned type should be inferred from the Repository class and the schema type which means we will get the result as a type which contains schema keys and Repository value type so we can not use it inappropriately. It is defined by ResultType. (Which I can not implement because I am not quite familiar with TypeScript type system).

But I think it makes really easy for up-layer program to use because we do not need to write GraphQL query ourselves and the underlying code can also handle paginate data properly which also will make it easier to use.

@ghost ghost moved this from Awaiting response to Support in JS May 19, 2021
@gr2m
Copy link
Contributor

gr2m commented Jun 11, 2021

I'm sorry I still don't follow 100%, but it sounds interesting. If you figure it out, please let me know! I'd love to improve the developer experience for sending GraphQL queries, ideally without adding a lot of code to octokit

@zhouzi
Copy link

zhouzi commented May 19, 2022

@frank-zsy are you looking to generate factories? This is exactly what zhouzi/graphql-codegen-factories does. For example, given the following schema:

type Repository {
  id: ID!
  name: String!
}

It generates something similar to:

export function createRepositoryMock(props: Partial<Repository>): Repository {
  return {
    __typename: "Repository",
    id: "",
    name: "",
    ...props,
  };
}

The default values can be customized. If that's what you are looking for, I would be happy to add it to my fork: zhouzi/graphql-schema

@frank-zsy
Copy link
Author

@zhouzi Great, I mean something like that. So like in the example we can use the type as a parameter and pass in as props and it will return the same type. I don't look into the code but how did you handle the array type like embedded edges and nodes which is quite annoying and the pagination is also a tricky work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Support Any questions, information, or general needs around the SDK or GitHub APIs
Projects
No open projects
JS
  
Support
Development

No branches or pull requests

4 participants