Skip to content

Commit 7c4196a

Browse files
committed
Add changeset
1 parent 0f5dda6 commit 7c4196a

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

.changeset/gold-frogs-explain.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
'@graphql-codegen/visitor-plugin-common': major
3+
'@graphql-codegen/typescript-operations': major
4+
'@graphql-codegen/typescript': major
5+
'@graphql-codegen/typescript-resolvers': major
6+
---
7+
8+
Implement Scalars with input/output types
9+
10+
In GraphQL, Scalar types can be different for client and server. For example, given the native GraphQL ID:
11+
- A client may send `string` or `number` in the input
12+
- A client receives `string` in its selection set (i.e output)
13+
- A server receives `string` in the resolver (GraphQL parses `string` or `number` received from the client to `string`)
14+
- A server may return `string` or `number` (GraphQL serializes the value to `string` before sending it to the client )
15+
16+
Currently, we represent every Scalar with only one type. This is what codegen generates as base type:
17+
18+
```ts
19+
export type Scalars = {
20+
ID: string;
21+
}
22+
```
23+
24+
Then, this is used in both input and output type e.g.
25+
26+
```ts
27+
export type Book = {
28+
__typename?: "Book";
29+
id: Scalars["ID"]; // Output's ID can be `string` 👍
30+
};
31+
32+
export type QueryBookArgs = {
33+
id: Scalars["ID"]; // Input's ID can be `string` or `number`. However, the type is only `string` here 👎
34+
};
35+
```
36+
37+
This PR extends each Scalar to have input and output:
38+
39+
```ts
40+
export type Scalars = {
41+
ID: {
42+
input: string | number;
43+
output: string;
44+
}
45+
}
46+
```
47+
48+
Then, each input/output GraphQL type can correctly refer to the correct input/output scalar type:
49+
50+
```ts
51+
export type Book = {
52+
__typename?: "Book";
53+
id: Scalars["ID"]['output']; // Output's ID can be `string` 👍
54+
};
55+
56+
export type QueryBookArgs = {
57+
id: Scalars["ID"]['input']; // Input's ID can be `string` or `number` 👍
58+
};
59+
```
60+
61+
Note that for `typescript-resolvers`, the type of ID needs to be inverted. However, the referenced types in GraphQL input/output types should still work correctly:
62+
63+
```ts
64+
export type Scalars = {
65+
ID: {
66+
input: string;
67+
output: string | number;
68+
}
69+
}
70+
71+
export type Book = {
72+
__typename?: "Book";
73+
id: Scalars["ID"]['output']; // Resolvers can return `string` or `number` in ID fields 👍
74+
};
75+
76+
export type QueryBookArgs = {
77+
id: Scalars["ID"]['input']; // Resolvers receive `string` in ID fields 👍
78+
};
79+
80+
export type ResolversTypes = {
81+
ID: ID: ResolverTypeWrapper<Scalars['ID']['output']>; // Resolvers can return `string` or `number` in ID fields 👍
82+
}
83+
84+
export type ResolversParentTypes = {
85+
ID: Scalars['ID']['output']; // Resolvers receive `string` or `number` from parents 👍
86+
};
87+
```
88+
89+
---
90+
91+
Config changes:
92+
93+
1. Scalars option can now take input/output types:
94+
95+
```ts
96+
config: {
97+
scalars: {
98+
ID: {
99+
input: 'string',
100+
output: 'string | number'
101+
}
102+
}
103+
}
104+
```
105+
106+
2. If a string is given (instead of an object with input/output fields), it will be used as both input and output types:
107+
108+
```ts
109+
config: {
110+
scalars: {
111+
ID: 'string' // Means it `string` will be used for both ID's input and output types
112+
}
113+
}
114+
```
115+
116+
3. BREAKING CHANGE: External module Scalar types need to be an object with input/output fields
117+
118+
```ts
119+
config: {
120+
scalars: {
121+
ID: './path/to/scalar-module'
122+
}
123+
}
124+
```
125+
126+
If correctly, wired up, the following will be generated:
127+
128+
```ts
129+
// Previously, imported `ID` type can be a primitive type, now it must be an object with input/output fields
130+
import { ID } from "./path/to/scalar-module";
131+
132+
export type Scalars = {
133+
ID: { input: ID['input']; output: ID['output']; }
134+
};
135+
```
136+
137+
---
138+
139+
BREAKING CHANGES: This changes Scalar types could be referenced in other plugins. If you are a plugin maintainer and reference Scalar, please update your plugin to use the correct input/output types.

0 commit comments

Comments
 (0)