Skip to content

Commit

Permalink
RFC: Add type params to Scalars.
Browse files Browse the repository at this point in the history
This incrementally adds to #574, however a broader solution is needed to create a mirroring between graphql type definitions and internal flow types.
  • Loading branch information
leebyron committed Dec 6, 2017
1 parent 2e09b81 commit b52da62
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 30 deletions.
49 changes: 25 additions & 24 deletions src/type/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import type { GraphQLSchema } from './schema';
* These are all of the possible kinds of types.
*/
export type GraphQLType =
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLObjectType
| GraphQLInterfaceType
| GraphQLUnionType
Expand Down Expand Up @@ -68,12 +68,12 @@ export function assertType(type: mixed): GraphQLType {
* These types may be used as input types for arguments and directives.
*/
type GraphQLInputType_<T> =
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLEnumType
| GraphQLInputObjectType
| GraphQLList<T>
| GraphQLNonNull<
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLEnumType
| GraphQLInputObjectType
| GraphQLList<T>,
Expand Down Expand Up @@ -102,14 +102,14 @@ export function assertInputType(type: ?GraphQLType): GraphQLInputType {
* These types may be used as output types as the result of fields.
*/
export type GraphQLOutputType =
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLObjectType
| GraphQLInterfaceType
| GraphQLUnionType
| GraphQLEnumType
| GraphQLList<GraphQLOutputType>
| GraphQLNonNull<
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLObjectType
| GraphQLInterfaceType
| GraphQLUnionType
Expand Down Expand Up @@ -140,7 +140,7 @@ export function assertOutputType(type: ?GraphQLType): GraphQLOutputType {
/**
* These types may describe types which may be leaf values.
*/
export type GraphQLLeafType = GraphQLScalarType | GraphQLEnumType;
export type GraphQLLeafType = GraphQLScalarType<any> | GraphQLEnumType;

export function isLeafType(type: ?GraphQLType): boolean %checks {
return type instanceof GraphQLScalarType || type instanceof GraphQLEnumType;
Expand Down Expand Up @@ -201,7 +201,7 @@ export function assertAbstractType(type: ?GraphQLType): GraphQLAbstractType {
* These types can all accept null as a value.
*/
type GraphQLNullableType_<T> =
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLObjectType
| GraphQLInterfaceType
| GraphQLUnionType
Expand All @@ -220,7 +220,7 @@ export function getNullableType<T: GraphQLType>(
* These named types do not include modifiers like List or NonNull.
*/
export type GraphQLNamedType =
| GraphQLScalarType
| GraphQLScalarType<any>
| GraphQLObjectType
| GraphQLInterfaceType
| GraphQLUnionType
Expand Down Expand Up @@ -297,18 +297,18 @@ function resolveThunk<T>(thunk: Thunk<T>): T {
* });
*
*/
export class GraphQLScalarType {
export class GraphQLScalarType<TInternal = any, TExternal = TInternal> {
name: string;
description: ?string;
astNode: ?ScalarTypeDefinitionNode;
_scalarConfig: GraphQLScalarTypeConfig<TInternal, TExternal>;

_scalarConfig: GraphQLScalarTypeConfig<*, *>;

constructor(config: GraphQLScalarTypeConfig<*, *>): void {
assertValidName(config.name);
constructor(config: GraphQLScalarTypeConfig<TInternal, TExternal>): void {
this.name = config.name;
this.description = config.description;
this.astNode = config.astNode;
this._scalarConfig = config;
assertValidName(config.name);
invariant(
typeof config.serialize === 'function',
`${this.name} must provide "serialize" function. If this custom Scalar ` +
Expand All @@ -323,11 +323,10 @@ export class GraphQLScalarType {
'functions.',
);
}
this._scalarConfig = config;
}

// Serializes an internal value to include in a response.
serialize(value: mixed): mixed {
serialize(value: mixed): TExternal | void {
const serializer = this._scalarConfig.serialize;
return serializer(value);
}
Expand All @@ -338,12 +337,11 @@ export class GraphQLScalarType {
}

// Parses an externally provided value to use as an input.
parseValue(value: mixed): mixed {
parseValue(value: mixed): TInternal | void {
const parser = this._scalarConfig.parseValue;
if (isInvalid(value)) {
return undefined;
if (!isInvalid(value)) {
return parser ? parser(value) : (value: any);
}
return parser ? parser(value) : value;
}

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

// Parses an externally provided literal value to use as an input.
parseLiteral(valueNode: ValueNode, variables: ?ObjMap<mixed>): mixed {
parseLiteral(
valueNode: ValueNode,
variables: ?ObjMap<mixed>,
): TInternal | void {
const parser = this._scalarConfig.parseLiteral;
return parser
? parser(valueNode, variables)
: valueFromASTUntyped(valueNode, variables);
: (valueFromASTUntyped(valueNode, variables): any);
}

toString(): string {
Expand All @@ -375,12 +376,12 @@ export type GraphQLScalarTypeConfig<TInternal, TExternal> = {
name: string,
description?: ?string,
astNode?: ?ScalarTypeDefinitionNode,
serialize: (value: mixed) => ?TExternal,
parseValue?: (value: mixed) => ?TInternal,
serialize: (value: mixed) => TExternal | void,
parseValue?: (value: mixed) => TInternal | void,
parseLiteral?: (
valueNode: ValueNode,
variables: ?ObjMap<mixed>,
) => ?TInternal,
) => TInternal | void,
};

/**
Expand Down
8 changes: 4 additions & 4 deletions src/type/scalars.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { GraphQLType } from './definition';
const MAX_INT = 2147483647;
const MIN_INT = -2147483648;

function coerceInt(value: mixed): ?number {
function coerceInt(value: mixed): number {
if (value === '') {
throw new TypeError(
'Int cannot represent non 32-bit signed integer value: (empty string)',
Expand Down Expand Up @@ -58,7 +58,7 @@ export const GraphQLInt = new GraphQLScalarType({
},
});

function coerceFloat(value: mixed): ?number {
function coerceFloat(value: mixed): number {
if (value === '') {
throw new TypeError(
'Float cannot represent non numeric value: (empty string)',
Expand Down Expand Up @@ -88,7 +88,7 @@ export const GraphQLFloat = new GraphQLScalarType({
},
});

function coerceString(value: mixed): ?string {
function coerceString(value: mixed): string {
if (Array.isArray(value)) {
throw new TypeError(
`String cannot represent an array value: [${String(value)}]`,
Expand Down Expand Up @@ -137,7 +137,7 @@ export const GraphQLID = new GraphQLScalarType({
},
});

export const specifiedScalarTypes: Array<GraphQLScalarType> = [
export const specifiedScalarTypes = [
GraphQLString,
GraphQLInt,
GraphQLFloat,
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/buildClientSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export function buildClientSchema(

function buildScalarDef(
scalarIntrospection: IntrospectionScalarType,
): GraphQLScalarType {
): GraphQLScalarType<mixed> {
return new GraphQLScalarType({
name: scalarIntrospection.name,
description: scalarIntrospection.description,
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/schemaPrinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export function printType(type: GraphQLType, options?: Options): string {
return printInputObject(type, options);
}

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

Expand Down

0 comments on commit b52da62

Please sign in to comment.