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

Nullable input type #55

Open
emcell opened this issue Jun 23, 2021 · 10 comments
Open

Nullable input type #55

emcell opened this issue Jun 23, 2021 · 10 comments
Labels
question Further information is requested

Comments

@emcell
Copy link

emcell commented Jun 23, 2021

I don't understand how to create a nullable input field


const t = createTypesFactory<ResolverContext>();
t.inputObjectType<{ asdf: string }>({
  name: 'test',
  fields: () => ({
    asdf: {
      type: t.NonNullInput(t.String),
      description: 'asdf',
    },
  }),
});

Am I missing something or is the function or type t.Input(t.String), just missing?

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jun 23, 2021

You have to wrap input field with t.arg: https://github.com/n1ru4l/character-overlay/blob/b7f3188a4a67241c2a1a928653dd01a833f6aa77/server/schema.ts#L187-L193

const GraphQLUpdateCharacterInput = t.inputObjectType({
  name: "UpdateCharacterInput",
  fields: () => ({
    editHash: t.arg(t.NonNullInput(t.String)),
    updates: t.arg(t.NonNullInput(GraphQLCharacterUpdateFields)),
  }),
});

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jun 30, 2021

@emcell Did this resolve your question?

@emcell
Copy link
Author

emcell commented Jun 30, 2021

Thank you for your answer. I understand it, but have not tried it yet. I'm working on this project in the next week again.

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jun 30, 2021

@sikanhe Is the distinction between NonNullInput and NonNull actually necessary or could we apply some TypeScript magic to make both use-cases inferring the correct type?

@Ericnr
Copy link
Contributor

Ericnr commented Jul 27, 2021

@n1ru4l that'd be nice. I'm currently trying to wrap gqtx's api into an api which is more pleasing and with better defaults (imo) ex:

  string: <T extends boolean = false>(opts?: {
    nullable: T;
  }): T extends true ? Scalar<string | null> : OutputType<Context, string> => {
    if (opts?.nullable === true) return t.String;
    return t.NonNull(t.String);
  },
  
  list: <Src>(ofType: OutputType<Context, Src>): OutputType<Context, Src[]> =>
    t.NonNull(t.List(ofType)),

problem is I cant use either string and list in inputObjectType because of t.NonNullInput and t.ListInput

@n1ru4l
Copy link
Collaborator

n1ru4l commented Jul 27, 2021

@Ericnr I did some changes over here: #52

Contributions are welcome :)

@Ericnr
Copy link
Contributor

Ericnr commented Jul 28, 2021

I'm not great with complex types, but I explored it for a little bit with a type that would be returned by .List and .NonNull

export type AllType<Ctx, Src, IsInput extends boolean> = IsInput extends true
  ? InputType<Src>
  : OutputType<Ctx, Src>;

in the end I couldn't get it to work, which is always my frustration when trying to do complicated TS stuff

@Ericnr
Copy link
Contributor

Ericnr commented Jul 28, 2021

here's the fork if anyone's interested Ericnr@d37c034

@tonyxiao
Copy link

  fields: () => ({
    asdf: {
      type: t.NonNullInput(t.String),
      description: 'asdf',
    },
  }),

Is this a valid way of defining? I need to explicitly return an array for fields and cannot use the object hash format.

@sikanhe sikanhe added the question Further information is requested label Jan 25, 2022
@visomi-dev
Copy link

Here my worked code, I expect help:

import type { Field } from 'gqtx';

import { createTypesFactory } from 'gqtx';

import type { GraphQLContext } from '~/entities/graphql';
import type { Color as ColorName } from '~/entities/ui';

type Color = { name: ColorName; value: string | null };

export type Fields = [
  Field<GraphQLContext, unknown, any, {}>,
  ...Field<GraphQLContext, unknown, any, {}>[],
];

export const typesFactory = createTypesFactory<GraphQLContext>();

export const ColorNameEnum = typesFactory.enumType<ColorName>({
  name: 'ColorName',
  values: [
    { name: 'pink', value: 'pink' },
    { name: 'purple', value: 'purple' },
    { name: 'blue', value: 'blue' },
    { name: 'green', value: 'green' },
    { name: 'yellow', value: 'yellow' },
    { name: 'custom', value: 'custom' },
  ],
});

export const ColorType = typesFactory.objectType<Color>({
  name: 'Color',
  description: 'A color',
  fields: () => [
    typesFactory.field({
      name: 'name',
      type: typesFactory.NonNull(ColorNameEnum),
    }),
    typesFactory.field({
      name: 'value',
      type: typesFactory.String,
    }),
  ],
});

// Here the example you need
export const ColorInputType = typesFactory.inputObjectType<Color>({
  name: 'ColorInput',
  fields: () => ({
    name: {
      type: typesFactory.NonNullInput(ColorNameEnum),
    },
    value: {
      type: typesFactory.String,
    },
  }),
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants