graphql-schema icon indicating copy to clipboard operation
graphql-schema copied to clipboard

[QUESTION]: specific `GitObject` usage? (ie, `Blob` & `Tree`)

Open noltron000 opened this issue 1 year ago • 1 comments

Question

Hi there! I was playing around with some queries in typescript. I was querying some trees/blobs off of the Repository object, and these results are typed like GitObject.

However, I notice that the types are a bit prohibitive. In schema.d.ts, I notice that Repository is defined like so:

// This type definition snippet is truncated to be more legible.
// Really, this extends lots of interfaces and has lots more attributes.
export type Repository = {
  /** A Git object in the repository */
  object?: Maybe<GitObject>;
}

You'll see that, GitObject is used here, although I'd like to tell TypeScript that its a Blob or Tree, both of which are types that can appear here. Instead of Maybe<GitObject>, the type definition should be something like Maybe<GitObject | Tree | Blob | /* ...etc */>. This lack of additional types is how its a bit prohibitive. I know I could use as in typescript to work around this, but I don't like to do so.

Is there a way to do this currently, with this generated schema? Am I missing something?

Current Usage

I have a work-around, but its slightly verbose:

// This is just using graphql from octokit...
import {graphqlWithAuth} from "./graphql-with-auth"

import {
  Blob,
  GitObject as BaseGitObject,
  Tree as BaseTree,
  TreeEntry as BaseTreeEntry,
  Repository as BaseRepository,
} from "@octokit/graphql-schema"

type Maybe<T> = T | null

// NOTE: Would be great if these types were powered by type-parameters sort of like this, out of the box!
type GitObject<T extends BaseGitObject = BaseGitObject> = T

interface Repository<Obj extends GitObject = GitObject> extends BaseRepository {
  object?: Maybe<Obj>
}

interface Tree<Obj extends GitObject = GitObject> extends BaseTree {
  entries?: Maybe<Array<TreeEntry<Obj>>>;
}

interface TreeEntry<Obj extends GitObject = GitObject> extends BaseTreeEntry {
  object?: Maybe<Obj>;
}

const callAPI = async ( ) => {
  const response = await graphqlWithAuth<{repository: Repository<Tree<Blob>>}>(MY_GITHUB_QUERY)

  // Just a dummy example to show this type works just fine.
  console.log(response.repository.object?.entries?.[0]?.object?.text)
}

Describe the need

This is sort of verbose, and it'd be lovely if I didn't have to write all these interfaces out.

For maintainers, if you don't find this relevant or something, feel free to just leave a comment and close this, I'm just trying to help! Thanks for your efforts!

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

noltron000 avatar Apr 10 '23 23:04 noltron000

Ah, my title isn't the best, let me see if I can revise that...

noltron000 avatar Apr 10 '23 23:04 noltron000