dotansimha / dotansimha/graphql-code-generator
Custom scalars cannot produce correct typings for both apollo client and server simultaneously
- Dominant language
- TypeScript
- Stars
- 11.3k
- Forks
- 1.4k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 23
Description
**Describe the bug**
When configuring custom scalars, it's not possible to have the generated types be simultaneously correct for both:
- apollo client queries
- apollo server resolvers
For example, with a Date scalar there are two options:
- `Date: Date`:
- ✅ This feels more semantically correct, we want to treat dates as dates
- ✅ It works for apollo server resolvers. You can do `return { someDate: new Date() }` and the types work
- (You also need to [configure](https://www.apollographql.com/docs/apollo-server/schema/custom-scalars/) how apollo (de-)serialises it)
- ❌ The type will be wrong on the client side. E.g. the generated types will incorrectly say that `myQuery.data.someDate` is a Date object, but it's actually a String
- `Date: String`:
- ✅ This matches how the field is serialised and sent over the network
- ✅ It is correct on the client side, i.e. `myQuery.data.someDate` will be correctly typed as a string
- ❌ The resolver type will expect you to return a string instead of a date. E.g. `return { someDate: new Date() }` will give a type error.
I think the root cause of this is that apollo server supports custom scalars pretty well, but apollo client doesn't support them at all. Until apollo client gets proper custom scalar support, I think that graphql-codegen should allow different types to be specified for:
- the thing that the resolver returns; and
- the thing that client receives
This would allow me return a date object from my resolver, and then have that come through as a string on the client.
**To Reproduce**
Sandbox here: https://codesandbox.io/s/intelligent-bird-pj5gj
1. My GraphQL schema:
```graphql
type Query {
user(id: ID!): User!
}
type User {
id: ID!
username: String!
email: String!
signUpDate: Date!
}
```
2. My GraphQL operations:
```graphql
query user {
user(id: 1) {
id
username
email
signUpDate
}
}
```
3. My `codegen.yml` config file:
```yml
schema: schema.graphql
documents: document.graphql
generates:
types.ts:
plugins:
- typescript
- typescript-operations
- typescript-resolvers
- typescript-react-apollo
config:
scalars:
Date: Date
```
**Expected behavior**
The user resolver should have `signUpDate: Date` in its return type, but `userUserQuery` should have `signUpDate: String` in its return type, to match the respective behaviour of apollo server and client.
**Environment:**
- OS: MacOS Big Sur
- `@graphql-codegen/cli": "1.21.4"`
- `@graphql-codegen/fragment-matcher": "2.0.1"`
- `@graphql-codegen/introspection": "1.18.2"`
- `@graphql-codegen/typescript": "1.22.0"`
- `@graphql-codegen/typescript-apollo-client-helpers": "^1.1.10"`
- `@graphql-codegen/typescript-operations": "1.17.16"`
- `@graphql-codegen/typescript-react-apollo": "2.2.4"`
- `@graphql-codegen/typescript-resolvers": "1.19.1"`
- NodeJS: 16.5.0
**Additional context**
Related issue: https://github.com/dotansimha/graphql-code-generator/pull/2757
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.