graphql-code-generator: [TypeScript Resolvers] Apollo Server resolvers types mismatch
I use typed resolvers generation and define my resolvers like:
import { QueryResolvers, MutationResolvers, SubscriptionResolvers, User } from './generated/graphql'
const query: QueryResolvers.Resolvers = {
allUsers: (root, args, ctx) => {
const result: User[] = []
return result
}
}
const mutation: MutationResolvers.Resolvers = {
signup: (root, args, ctx) => {
const res = ctx.gql.mutation.createUser({
input: {
user: {
firstName: 'John Doe'
}
}
})
const result: User = { firstname: 'asdf', lastname: 'asdfasdf' }
return result
}
}
export default {
mutation,
query
}
When it comes to configure apollo-server like this:
import resolvers from './app/resolvers'
const server = new ApolloServer({
typeDefs,
resolvers,
mocks: true,
context: (c: any) => ({
...c,
orm: connection,
gql: postgraphileConnection
})
})
then apollo-server gives an error about types mismatch:
Type '{ mutation: Resolvers<GqlContext, {}>; query: Resolvers<GqlContext, {}>; }' is not assignable to type 'IResolvers<any, any>'.
Property 'mutation' is incompatible with index signature.
Type 'Resolvers<GqlContext, {}>' is not assignable to type '(() => any) | GraphQLScalarType | IEnumResolver | IResolverObject<any, any> | IResolverOptions<any, any>'.
Type 'Resolvers<GqlContext, {}>' is not assignable to type 'IResolverObject<any, any>'.
Index signature is missing in type 'Resolvers<GqlContext, {}>'.ts(2322)
types.d.ts(28, 5): The expected type comes from property 'resolvers' which is declared here on type 'Config & { cors?: boolean | CorsOptions; }'
What should be done in order to solve it?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 14
- Comments: 29 (8 by maintainers)
Commits related to this issue
- [TypeScript Resolvers] Apollo Server resolvers types missmatch #1133 — committed to dotansimha/graphql-code-generator by ardatan 5 years ago
For anyone wondering where to put the
useIndexSignature: true, mycodegen.ymllooks like this (see the last 2 lines):It’s hidden behind a flag because the type safety is less strict then.
Try
useIndexSignature: true@dotansimha You are absolutely right, it’s there, and I’ve overlooked it. I am a newbie to TS and the
index signaturekeywords were not catching my attention TBH.I guess my larger problem was that I falsely expected it to “just work”, considering that JS + Apollo is probably the most common starting point for a new GraphQL development - which is not really a problem of the codegen, but rather of Apollo.
I may suggest dropping a code snippet to that section, so it’s just a bit more eye-catchy. Or maybe rephrase the doc like
By default Apollo Server will not work with generated Resolver interface....Thanks!
P.S. BTW, I didn’t want to compromise type safety of generated interfaces, so I ended up with this trick:
Thanks @mariusmarais, this helped:
@dzmitry-kankalovich It’s documented in our docs website, you can even find it easily in the search:
And there is a section for integration with Apollo Server: https://graphql-code-generator.com/docs/plugins/typescript-resolvers#integration-with-apollo-server
This is not a “known issue”, because the resolver signature is agnostic to any GraphQL platform. If you wish to have it running with Apollo Server, you’ll need to add the flag, because Apollo-Server expects a different signature than plain
graphql.js.@kamilkisiela would you mind editing your comment to remove the
s? (and thanks @P4sca1 )Hello everyone, I think I can help 😄
As @mariusmarais said Apollo resolvers are defined as string indexed dictionaries. Which is good because it allows dynamic propery access in strict mode like
resolvers[varableName]and exclude otherwise possible number/symbols indexes.There are few ways to provide string index signatures, my usual:
And now you can do:
@kamilkisiela I think it’s not too weird workaround 😉
Btw. You can do something about it -there is currently open issue with ‘help wanted’ in typescript main repo to allow inferring index signatures from object literals^^
If
graphql-code-generator-typescript-serveris meant only for Apollo - this could be added to generated code. Otherwise - I think everything is ok (because removing index signatures is somehow harder than adding them^^) - maybe sb can mention of this ‘trick’ in docs.//EDIT: Frankly I cannot think of use case when string index signature would become an issue, if you know one - please tell. Maybe this should be added to generate code for easier use. (@dotansimha I can PR it if you want)
For anyone else who lands here and
useIndexSignature: trueisn’t working — you have to kill the codegen server and restart it. The config hot reload doesn’t work for this.I literally spent an entire day on this problem. I wish things like this would be mentioned in README, something about known issues.
@ankitjena which version do you use? It seems like your configuration is valid, the
useIndexSignature: trueshould make it compatible with Apollo server.@panzelva it was fixed in the recent refactor, and it will be available soon in 1.0.0.
Hello, I am not sure if relevant to this issue, but I am getting this error:
I am using
typescript@3.3.3333andgraphql-code-generator@0.18.0Fixed in 0.18.0 🎉
@noahseger No - Au Contraire 😏
We’re not removing typing because it’s type intersection. Prop value needs to be
any & whateverwasbefore = whateverwasbefore.Lazy Example <= turn all the strict in Options!
The only thing lost with it is allowing accessing other typed indexes and receiving proper undefined type. (which is good thing for me usually - reflecting js, allowing lookups of props - and that’s why I proposed it)
It could be tightened a bit with this:
Or there is another method using mapped type that is the strictest possible (nor access nor assign) :
It all works, check in my lazy example 🙃
I can confirm it’s the issue @mariusmarais mentioned. I don’t think we can do anything about it right now, without implementing some weird workarounds. It’s something related to TypeScript, not GraphQL Code Generator, at least for now.
As I understand it, the reason for this is because Apollo’s
IResolversis defined as a dictionary / with an index signature (see the code).This is not the same as an object with keys, even if the keys would match the index type. TS 2.0 was supposed to fix this (I think?) but it still doesn’t work for me.
I would do the following:
Although it doesn’t really fix it.
(FYI, I also have
QueryandMutation, etc., and not lower-case.)