I am attempting to generate types to use inside my graphQl server to make my resolvers easier to maintain. I hoping that I can do that using this project.
I am running into an issue with how optional/mandatory fields are generated. I am hoping that someone can suggest a workaround for me.
Schema:
type Query {
people(): [Person!]!
}
# FirstName, LastName & BirthDate are manditory. MiddleName is optional.
Person {
firstName: String!
middleName: String
lastName: String!
birthDate: BirthDate!
}
BirthDate {
...
}
When I generate a typescript class for this object
($(npm bin)/gql-gen --file schema.json --template typescript), I get the following:
export interface Person {
firstName: String
middleName?: String
lastName: String
birthDate: BirthDate
}
export interface Query {
...
}
export interface BirthDate {
...
}
Unfortunately, these objects are not extremely useful to me inside my GraphQl resolvers. Inside my resolvers, I populate fields lazily. What I would like to be generated is the following:
export interface Person {
firstName?: String
middleName?: String
lastName?: String
birthDate?: BirthDate
}
export interface Query {
...
}
export interface BirthDate {
...
}
To provide complete context, this is an example resolver. You can see that I am getting a compiler error here:
const personResolver: IFieldResolver<any, any> = (parentObject: any,
args: any,
context: any,
info: GraphQLResolveInfo): Promise<Person[]> => {
const firstName: string = loadFirstNameFromDb(..);
const lastName: string = loadlastNameFromDb(..);
const middleName: string|undefined = loadMiddleNameFromDb(..);
# NOTE: We have a separate resolver for BirthDate. Birthdate is
# not known here.
#
# This causes the following TS Error:
#
# Error:(7, 15) TS2322: Type '...' is not assignable to type 'Person'.
# Property 'birthDate' is missing in type '...'.
const person: Person = {
firstName: firstName,
middleName: middleName,
lastName: lastName,
};
return person
};
const siteResolver: IFieldResolver<any, any> = (parentObject: Person,
args: any,
context: any,
info: GraphQLResolveInfo): Promise<BirthDate> => {
...
};
const resolvers: IResolvers = {
Query: {
...
},
Person:
Order: {
reports: () => [],
studies: () => [],
site: siteResolver,
},
};
I have read through the other threads on this subject, but am still not sure if my use case is valid. Other threads:
Thanks!
You can always use Partial<Person> to turn all those fields as optional when you need to. I don't think it makes sense change this on a generator side as in your schema you clearly have requirement flag for those fields. Or you can make your own templates I guess :)
@FredyC is right, use Partial<Person> to achieve this functionality.
Yes you can you Partial<SomeModel> but what you can do if you have nested long object?
For instance:
interface Post {
id: number,
creator?: Maybe<Creator>
latestComment?: Maybe<Comment>
}
interface Creator {
id: number,
firstName: string
email: string,
createdAt: string,
updatedAt: string,
}
interface Comment {
id: number,
creator: Maybe<Creator>,
body: string,
dateTime: string
}
Let's say from GraphQL server I want only few fields from creator
I'm writing tests for my component that could show post. That component have @Input or prop (angular/react) that represent one post.
In test I mocked my post object with only necessary fields for my component, But I got typescript error Field createdAt is missing from Creator type...
So my suggestion is adding config option for generate all field optional.
This would also be useful for creating mock resolvers for use with graphql-tools' makeExecutableSchema.
Most helpful comment
Yes you can you
Partial<SomeModel>but what you can do if you have nested long object?For instance:
Let's say from GraphQL server I want only few fields from
creatorI'm writing tests for my component that could show post. That component have
@Inputorprop(angular/react) that represent one post.In test I mocked my post object with only necessary fields for my component, But I got typescript error
Field createdAt is missing from Creator type...So my suggestion is adding config option for generate all field
optional.