You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update typescript, typescript-operations and typescript-resolvers plugins Scalars input/output type (#9375)
* Implement Scalar input/output types
- Use Scalars input/output in base typescript plugin
- Use Scalars in typescript-operations plugin
- Update typescript-resolvers to support input/output
- Update related website docs
* Make version bump minor
* Fix changeset
* Fix unit tests
* Update tests
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
+
exporttypeScalars= {
20
+
ID:string;
21
+
}
22
+
```
23
+
24
+
Then, this is used in both input and output type e.g.
25
+
26
+
```ts
27
+
exporttypeBook= {
28
+
__typename?:"Book";
29
+
id:Scalars["ID"]; // Output's ID can be `string` 👍
30
+
};
31
+
32
+
exporttypeQueryBookArgs= {
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
+
exporttypeScalars= {
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
+
exporttypeBook= {
52
+
__typename?:"Book";
53
+
id:Scalars["ID"]['output']; // Output's ID can be `string` 👍
54
+
};
55
+
56
+
exporttypeQueryBookArgs= {
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
+
exporttypeScalars= {
65
+
ID: {
66
+
input:string;
67
+
output:string|number;
68
+
}
69
+
}
70
+
71
+
exporttypeBook= {
72
+
__typename?:"Book";
73
+
id:Scalars["ID"]['output']; // Resolvers can return `string` or `number` in ID fields 👍
74
+
};
75
+
76
+
exporttypeQueryBookArgs= {
77
+
id:Scalars["ID"]['input']; // Resolvers receive `string` in ID fields 👍
78
+
};
79
+
80
+
exporttypeResolversTypes= {
81
+
ID:ID:ResolverTypeWrapper<Scalars['ID']['output']>; // Resolvers can return `string` or `number` in ID fields 👍
82
+
}
83
+
84
+
exporttypeResolversParentTypes= {
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'// This means `string` will be used for both ID's input and output types
112
+
}
113
+
}
114
+
```
115
+
116
+
3. (Potential) 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
+
exporttypeScalars= {
133
+
ID: { input:ID['input']; output:ID['output']; }
134
+
};
135
+
```
136
+
137
+
---
138
+
139
+
(Potential) BREAKING CHANGE: This changes Scalar types which 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