Skip to content

Instantly share code, notes, and snippets.

@acro5piano
Created June 28, 2024 09:32
Show Gist options
  • Save acro5piano/7ced5400333b3b8cfd8020fbffa1ca71 to your computer and use it in GitHub Desktop.
Save acro5piano/7ced5400333b3b8cfd8020fbffa1ca71 to your computer and use it in GitHub Desktop.
gqtx-like library idea
type ScalarField = 'ID' | 'String'

type ResolvableField<Out extends ObjectType<any>> = {
  type: Out
  resolve: () => Out extends ObjectType<infer Src> ? Src : never
}

export class ObjectType<Src> {
  constructor(public name: string) {}

  field<Name extends string, T extends ObjectType<any>>(
    _name: Name,
    _type: Name extends keyof Src ? ScalarField : () => ResolvableField<T>,
  ): this {
    return this
  }
}

type UserModel = {
  id: string
  userName: string
}

const User = new ObjectType<UserModel>('User')
  .field('id', 'ID')
  .field('formattedName', 'String')
  .field('company', () => ({
    type: Company,
    resolve() {
      return {
        id: 'foo',
      }
    },
  }))

type CompanyModel = {
  id: string
  companyName: string
}

export const Company: ObjectType<CompanyModel> = new ObjectType<CompanyModel>(
  'Company',
)
  .field('id', 'ID')
  .field('companyName', 'String')
  .field('owner', () => ({
    type: User,
    resolve() {
      return {
        id: 'hoge',
        userName: 'fuga',
      }
    },
  }))

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment