Skip to content

Commit 7c95784

Browse files
committed
RFC: Add type params to Scalars.
This incrementally adds to #574, however a broader solution is needed to create a mirroring between graphql type definitions and internal flow types.
1 parent 2e09b81 commit 7c95784

File tree

4 files changed

+32
-31
lines changed

4 files changed

+32
-31
lines changed

src/type/definition.js

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import type { GraphQLSchema } from './schema';
3737
* These are all of the possible kinds of types.
3838
*/
3939
export type GraphQLType =
40-
| GraphQLScalarType
40+
| GraphQLScalarType<any>
4141
| GraphQLObjectType
4242
| GraphQLInterfaceType
4343
| GraphQLUnionType
@@ -68,12 +68,12 @@ export function assertType(type: mixed): GraphQLType {
6868
* These types may be used as input types for arguments and directives.
6969
*/
7070
type GraphQLInputType_<T> =
71-
| GraphQLScalarType
71+
| GraphQLScalarType<any>
7272
| GraphQLEnumType
7373
| GraphQLInputObjectType
7474
| GraphQLList<T>
7575
| GraphQLNonNull<
76-
| GraphQLScalarType
76+
| GraphQLScalarType<any>
7777
| GraphQLEnumType
7878
| GraphQLInputObjectType
7979
| GraphQLList<T>,
@@ -102,14 +102,14 @@ export function assertInputType(type: ?GraphQLType): GraphQLInputType {
102102
* These types may be used as output types as the result of fields.
103103
*/
104104
export type GraphQLOutputType =
105-
| GraphQLScalarType
105+
| GraphQLScalarType<any>
106106
| GraphQLObjectType
107107
| GraphQLInterfaceType
108108
| GraphQLUnionType
109109
| GraphQLEnumType
110110
| GraphQLList<GraphQLOutputType>
111111
| GraphQLNonNull<
112-
| GraphQLScalarType
112+
| GraphQLScalarType<any>
113113
| GraphQLObjectType
114114
| GraphQLInterfaceType
115115
| GraphQLUnionType
@@ -140,7 +140,7 @@ export function assertOutputType(type: ?GraphQLType): GraphQLOutputType {
140140
/**
141141
* These types may describe types which may be leaf values.
142142
*/
143-
export type GraphQLLeafType = GraphQLScalarType | GraphQLEnumType;
143+
export type GraphQLLeafType = GraphQLScalarType<any> | GraphQLEnumType;
144144

145145
export function isLeafType(type: ?GraphQLType): boolean %checks {
146146
return type instanceof GraphQLScalarType || type instanceof GraphQLEnumType;
@@ -201,7 +201,7 @@ export function assertAbstractType(type: ?GraphQLType): GraphQLAbstractType {
201201
* These types can all accept null as a value.
202202
*/
203203
type GraphQLNullableType_<T> =
204-
| GraphQLScalarType
204+
| GraphQLScalarType<any>
205205
| GraphQLObjectType
206206
| GraphQLInterfaceType
207207
| GraphQLUnionType
@@ -220,7 +220,7 @@ export function getNullableType<T: GraphQLType>(
220220
* These named types do not include modifiers like List or NonNull.
221221
*/
222222
export type GraphQLNamedType =
223-
| GraphQLScalarType
223+
| GraphQLScalarType<any>
224224
| GraphQLObjectType
225225
| GraphQLInterfaceType
226226
| GraphQLUnionType
@@ -297,18 +297,18 @@ function resolveThunk<T>(thunk: Thunk<T>): T {
297297
* });
298298
*
299299
*/
300-
export class GraphQLScalarType {
300+
export class GraphQLScalarType<TInternal, TExternal = TInternal> {
301301
name: string;
302302
description: ?string;
303303
astNode: ?ScalarTypeDefinitionNode;
304+
_scalarConfig: GraphQLScalarTypeConfig<TInternal, TExternal>;
304305

305-
_scalarConfig: GraphQLScalarTypeConfig<*, *>;
306-
307-
constructor(config: GraphQLScalarTypeConfig<*, *>): void {
308-
assertValidName(config.name);
306+
constructor(config: GraphQLScalarTypeConfig<TInternal, TExternal>): void {
309307
this.name = config.name;
310308
this.description = config.description;
311309
this.astNode = config.astNode;
310+
this._scalarConfig = config;
311+
assertValidName(config.name);
312312
invariant(
313313
typeof config.serialize === 'function',
314314
`${this.name} must provide "serialize" function. If this custom Scalar ` +
@@ -323,11 +323,10 @@ export class GraphQLScalarType {
323323
'functions.',
324324
);
325325
}
326-
this._scalarConfig = config;
327326
}
328327

329328
// Serializes an internal value to include in a response.
330-
serialize(value: mixed): mixed {
329+
serialize(value: mixed): TExternal | void {
331330
const serializer = this._scalarConfig.serialize;
332331
return serializer(value);
333332
}
@@ -338,12 +337,11 @@ export class GraphQLScalarType {
338337
}
339338

340339
// Parses an externally provided value to use as an input.
341-
parseValue(value: mixed): mixed {
340+
parseValue(value: mixed): TInternal | void {
342341
const parser = this._scalarConfig.parseValue;
343-
if (isInvalid(value)) {
344-
return undefined;
342+
if (!isInvalid(value)) {
343+
return parser ? parser(value) : (value: any);
345344
}
346-
return parser ? parser(value) : value;
347345
}
348346

349347
// Determines if an internal value is valid for this type.
@@ -352,11 +350,14 @@ export class GraphQLScalarType {
352350
}
353351

354352
// Parses an externally provided literal value to use as an input.
355-
parseLiteral(valueNode: ValueNode, variables: ?ObjMap<mixed>): mixed {
353+
parseLiteral(
354+
valueNode: ValueNode,
355+
variables: ?ObjMap<mixed>,
356+
): TInternal | void {
356357
const parser = this._scalarConfig.parseLiteral;
357358
return parser
358359
? parser(valueNode, variables)
359-
: valueFromASTUntyped(valueNode, variables);
360+
: (valueFromASTUntyped(valueNode, variables): any);
360361
}
361362

362363
toString(): string {
@@ -371,16 +372,16 @@ export class GraphQLScalarType {
371372
GraphQLScalarType.prototype.toJSON = GraphQLScalarType.prototype.inspect =
372373
GraphQLScalarType.prototype.toString;
373374

374-
export type GraphQLScalarTypeConfig<TInternal, TExternal> = {
375+
export type GraphQLScalarTypeConfig<TInternal, TExternal = TInternal> = {
375376
name: string,
376377
description?: ?string,
377378
astNode?: ?ScalarTypeDefinitionNode,
378-
serialize: (value: mixed) => ?TExternal,
379-
parseValue?: (value: mixed) => ?TInternal,
379+
serialize: (value: mixed) => TExternal | void,
380+
parseValue?: (value: mixed) => TInternal | void,
380381
parseLiteral?: (
381382
valueNode: ValueNode,
382383
variables: ?ObjMap<mixed>,
383-
) => ?TInternal,
384+
) => TInternal | void,
384385
};
385386

386387
/**

src/type/scalars.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { GraphQLType } from './definition';
1919
const MAX_INT = 2147483647;
2020
const MIN_INT = -2147483648;
2121

22-
function coerceInt(value: mixed): ?number {
22+
function coerceInt(value: mixed): number {
2323
if (value === '') {
2424
throw new TypeError(
2525
'Int cannot represent non 32-bit signed integer value: (empty string)',
@@ -58,7 +58,7 @@ export const GraphQLInt = new GraphQLScalarType({
5858
},
5959
});
6060

61-
function coerceFloat(value: mixed): ?number {
61+
function coerceFloat(value: mixed): number {
6262
if (value === '') {
6363
throw new TypeError(
6464
'Float cannot represent non numeric value: (empty string)',
@@ -88,7 +88,7 @@ export const GraphQLFloat = new GraphQLScalarType({
8888
},
8989
});
9090

91-
function coerceString(value: mixed): ?string {
91+
function coerceString(value: mixed): string {
9292
if (Array.isArray(value)) {
9393
throw new TypeError(
9494
`String cannot represent an array value: [${String(value)}]`,
@@ -137,7 +137,7 @@ export const GraphQLID = new GraphQLScalarType({
137137
},
138138
});
139139

140-
export const specifiedScalarTypes: Array<GraphQLScalarType> = [
140+
export const specifiedScalarTypes = [
141141
GraphQLString,
142142
GraphQLInt,
143143
GraphQLFloat,

src/utilities/buildClientSchema.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export function buildClientSchema(
204204

205205
function buildScalarDef(
206206
scalarIntrospection: IntrospectionScalarType,
207-
): GraphQLScalarType {
207+
): GraphQLScalarType<mixed> {
208208
return new GraphQLScalarType({
209209
name: scalarIntrospection.name,
210210
description: scalarIntrospection.description,

src/utilities/schemaPrinter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function printType(type: GraphQLType, options?: Options): string {
161161
return printInputObject(type, options);
162162
}
163163

164-
function printScalar(type: GraphQLScalarType, options): string {
164+
function printScalar(type: GraphQLScalarType<any>, options): string {
165165
return printDescription(options, type) + `scalar ${type.name}`;
166166
}
167167

0 commit comments

Comments
 (0)