Skip to content

Commit

Permalink
Use flow %checks to reduce occurance of :any
Browse files Browse the repository at this point in the history
This uses a pre-release flow feature to provide predicate functions with more type checking power. It also breaks apart some functions into multiple declare function statements for cases where more specific input types result in more specific output types.
  • Loading branch information
leebyron committed Jan 27, 2017
1 parent 8122ba7 commit 14caa05
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 97 deletions.
3 changes: 1 addition & 2 deletions src/execution/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,7 @@ function doesFragmentConditionMatch(
return true;
}
if (isAbstractType(conditionalType)) {
const abstractType = ((conditionalType: any): GraphQLAbstractType);
return exeContext.schema.isPossibleType(abstractType, type);
return exeContext.schema.isPossibleType(conditionalType, type);
}
return false;
}
Expand Down
3 changes: 1 addition & 2 deletions src/execution/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,14 @@ export function getVariableValues(
for (let i = 0; i < varDefNodes.length; i++) {
const varDefNode = varDefNodes[i];
const varName = varDefNode.variable.name.value;
let varType = typeFromAST(schema, varDefNode.type);
const varType = typeFromAST(schema, varDefNode.type);
if (!isInputType(varType)) {
throw new GraphQLError(
`Variable "$${varName}" expected value of type ` +
`"${print(varDefNode.type)}" which cannot be used as an input type.`,
[ varDefNode.type ]
);
}
varType = ((varType: any): GraphQLInputType);

const value = inputs[varName];
if (isInvalid(value)) {
Expand Down
75 changes: 41 additions & 34 deletions src/type/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ export type GraphQLInputType =
GraphQLList<GraphQLInputType>
>;

export function isInputType(type: ?GraphQLType): boolean {
const namedType = getNamedType(type);
export function isInputType(type: ?GraphQLType)/* : boolean %checks */ {
return (
namedType instanceof GraphQLScalarType ||
namedType instanceof GraphQLEnumType ||
namedType instanceof GraphQLInputObjectType
type instanceof GraphQLScalarType ||
type instanceof GraphQLEnumType ||
type instanceof GraphQLInputObjectType ||
type instanceof GraphQLNonNull && isInputType(type.ofType) ||
type instanceof GraphQLList && isInputType(type.ofType)
);
}

Expand All @@ -86,7 +87,7 @@ export function assertInputType(type: ?GraphQLType): GraphQLInputType {
isInputType(type),
`Expected ${String(type)} to be a GraphQL input type.`
);
return (type: any);
return type;
}

/**
Expand All @@ -108,14 +109,15 @@ export type GraphQLOutputType =
GraphQLList<GraphQLOutputType>
>;

export function isOutputType(type: ?GraphQLType): boolean {
const namedType = getNamedType(type);
export function isOutputType(type: ?GraphQLType)/* : boolean %checks */ {
return (
namedType instanceof GraphQLScalarType ||
namedType instanceof GraphQLObjectType ||
namedType instanceof GraphQLInterfaceType ||
namedType instanceof GraphQLUnionType ||
namedType instanceof GraphQLEnumType
type instanceof GraphQLScalarType ||
type instanceof GraphQLObjectType ||
type instanceof GraphQLInterfaceType ||
type instanceof GraphQLUnionType ||
type instanceof GraphQLEnumType ||
type instanceof GraphQLNonNull && isOutputType(type.ofType) ||
type instanceof GraphQLList && isOutputType(type.ofType)
);
}

Expand All @@ -124,7 +126,7 @@ export function assertOutputType(type: ?GraphQLType): GraphQLOutputType {
isOutputType(type),
`Expected ${String(type)} to be a GraphQL output type.`,
);
return (type: any);
return type;
}

/**
Expand All @@ -134,11 +136,10 @@ export type GraphQLLeafType =
GraphQLScalarType |
GraphQLEnumType;

export function isLeafType(type: ?GraphQLType): boolean {
const namedType = getNamedType(type);
export function isLeafType(type: ?GraphQLType)/* : boolean %checks */ {
return (
namedType instanceof GraphQLScalarType ||
namedType instanceof GraphQLEnumType
type instanceof GraphQLScalarType ||
type instanceof GraphQLEnumType
);
}

Expand All @@ -147,7 +148,7 @@ export function assertLeafType(type: ?GraphQLType): GraphQLLeafType {
isLeafType(type),
`Expected ${String(type)} to be a GraphQL leaf type.`,
);
return (type: any);
return type;
}

/**
Expand All @@ -158,7 +159,7 @@ export type GraphQLCompositeType =
GraphQLInterfaceType |
GraphQLUnionType;

export function isCompositeType(type: ?GraphQLType): boolean {
export function isCompositeType(type: ?GraphQLType)/* : boolean %checks */ {
return (
type instanceof GraphQLObjectType ||
type instanceof GraphQLInterfaceType ||
Expand All @@ -171,7 +172,7 @@ export function assertCompositeType(type: ?GraphQLType): GraphQLCompositeType {
isCompositeType(type),
`Expected ${String(type)} to be a GraphQL composite type.`,
);
return (type: any);
return type;
}

/**
Expand All @@ -181,7 +182,7 @@ export type GraphQLAbstractType =
GraphQLInterfaceType |
GraphQLUnionType;

export function isAbstractType(type: ?GraphQLType): boolean {
export function isAbstractType(type: ?GraphQLType)/* : boolean %checks */ {
return (
type instanceof GraphQLInterfaceType ||
type instanceof GraphQLUnionType
Expand All @@ -193,7 +194,7 @@ export function assertAbstractType(type: ?GraphQLType): GraphQLAbstractType {
isAbstractType(type),
`Expected ${String(type)} to be a GraphQL abstract type.`,
);
return (type: any);
return type;
}

/**
Expand Down Expand Up @@ -225,7 +226,7 @@ export type GraphQLNamedType =
GraphQLEnumType |
GraphQLInputObjectType;

export function isNamedType(type: ?GraphQLType): boolean {
export function isNamedType(type: ?GraphQLType)/* : boolean %checks */ {
return (
type instanceof GraphQLScalarType ||
type instanceof GraphQLObjectType ||
Expand All @@ -241,18 +242,24 @@ export function assertNamedType(type: ?GraphQLType): GraphQLNamedType {
isNamedType(type),
`Expected ${String(type)} to be a GraphQL named type.`,
);
return (type: any);
return type;
}

export function getNamedType(type: ?GraphQLType): ?GraphQLNamedType {
let unmodifiedType = type;
while (
unmodifiedType instanceof GraphQLList ||
unmodifiedType instanceof GraphQLNonNull
) {
unmodifiedType = unmodifiedType.ofType;
/* eslint-disable no-redeclare */
declare function getNamedType(type: void | null): void;
declare function getNamedType(type: GraphQLType): GraphQLNamedType;
export function getNamedType(type) {
/* eslint-enable no-redeclare */
if (type) {
let unmodifiedType = type;
while (
unmodifiedType instanceof GraphQLList ||
unmodifiedType instanceof GraphQLNonNull
) {
unmodifiedType = unmodifiedType.ofType;
}
return unmodifiedType;
}
return unmodifiedType;
}


Expand Down Expand Up @@ -546,7 +553,7 @@ function isPlainObj(obj) {
}

// If a resolver is defined, it must be a function.
function isValidResolver(resolver: any): boolean {
function isValidResolver(resolver: mixed): boolean {
return (resolver == null || typeof resolver === 'function');
}

Expand Down
19 changes: 11 additions & 8 deletions src/utilities/TypeInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
GraphQLInputObjectType,
GraphQLEnumType,
GraphQLList,
isInputType,
isOutputType,
} from '../type/definition';
import type {
GraphQLType,
Expand Down Expand Up @@ -117,12 +119,9 @@ export class TypeInfo {
switch (node.kind) {
case Kind.SELECTION_SET:
const namedType = getNamedType(this.getType());
let compositeType: ?GraphQLCompositeType;
if (isCompositeType(namedType)) {
// isCompositeType is a type refining predicate, so this is safe.
compositeType = ((namedType: any): GraphQLCompositeType);
}
this._parentTypeStack.push(compositeType);
this._parentTypeStack.push(
isCompositeType(namedType) ? namedType : undefined
);
break;
case Kind.FIELD:
const parentType = this.getParentType();
Expand Down Expand Up @@ -153,11 +152,15 @@ export class TypeInfo {
const outputType = typeConditionAST ?
typeFromAST(schema, typeConditionAST) :
this.getType();
this._typeStack.push(((outputType: any): GraphQLOutputType));
this._typeStack.push(
isOutputType(outputType) ? outputType : undefined
);
break;
case Kind.VARIABLE_DEFINITION:
const inputType = typeFromAST(schema, node.type);
this._inputTypeStack.push(((inputType: any): GraphQLInputType));
this._inputTypeStack.push(
isInputType(inputType) ? inputType : undefined
);
break;
case Kind.ARGUMENT:
let argDef;
Expand Down
12 changes: 4 additions & 8 deletions src/utilities/buildASTSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ import {
GraphQLInputObjectType,
GraphQLList,
GraphQLNonNull,
isInputType,
isOutputType,
assertInputType,
assertOutputType,
} from '../type/definition';

import type {
Expand Down Expand Up @@ -299,15 +299,11 @@ export function buildASTSchema(ast: DocumentNode): GraphQLSchema {
}

function produceInputType(typeNode: TypeNode): GraphQLInputType {
const type = produceType(typeNode);
invariant(isInputType(type), 'Expected Input type.');
return (type: any);
return assertInputType(produceType(typeNode));
}

function produceOutputType(typeNode: TypeNode): GraphQLOutputType {
const type = produceType(typeNode);
invariant(isOutputType(type), 'Expected Output type.');
return (type: any);
return assertOutputType(produceType(typeNode));
}

function produceObjectType(typeNode: TypeNode): GraphQLObjectType {
Expand Down
8 changes: 4 additions & 4 deletions src/utilities/buildClientSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export function buildClientSchema(
isInputType(type),
'Introspection must provide input type for arguments.'
);
return (type: any);
return type;
}

function getOutputType(typeRef: IntrospectionTypeRef): GraphQLOutputType {
Expand All @@ -171,7 +171,7 @@ export function buildClientSchema(
isOutputType(type),
'Introspection must provide output type for fields.'
);
return (type: any);
return type;
}

function getObjectType(typeRef: IntrospectionTypeRef): GraphQLObjectType {
Expand All @@ -180,7 +180,7 @@ export function buildClientSchema(
type instanceof GraphQLObjectType,
'Introspection must provide object type for possibleTypes.'
);
return (type: any);
return type;
}

function getInterfaceType(
Expand All @@ -191,7 +191,7 @@ export function buildClientSchema(
type instanceof GraphQLInterfaceType,
'Introspection must provide interface type for interfaces.'
);
return (type: any);
return type;
}


Expand Down
16 changes: 6 additions & 10 deletions src/utilities/extendSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import {
GraphQLScalarType,
GraphQLEnumType,
GraphQLInputObjectType,
isInputType,
isOutputType,
assertInputType,
assertOutputType,
} from '../type/definition';

import {
Expand Down Expand Up @@ -295,15 +295,11 @@ export function extendSchema(
}

function getInputTypeFromAST(node: NamedTypeNode): GraphQLInputType {
const type = getTypeFromAST(node);
invariant(isInputType(type), 'Must be Input type.');
return (type: any);
return assertInputType(getTypeFromAST(node));
}

function getOutputTypeFromAST(node: NamedTypeNode): GraphQLOutputType {
const type = getTypeFromAST(node);
invariant(isOutputType(type), 'Must be Output type.');
return (type: any);
return assertOutputType(getTypeFromAST(node));
}

// Given a name, returns a type from either the existing schema or an
Expand Down Expand Up @@ -441,10 +437,10 @@ export function extendSchema(

function extendFieldType<T: GraphQLType>(typeDef: T): T {
if (typeDef instanceof GraphQLList) {
return (new GraphQLList(extendFieldType(typeDef.ofType)): any);
return new GraphQLList(extendFieldType(typeDef.ofType));
}
if (typeDef instanceof GraphQLNonNull) {
return (new GraphQLNonNull(extendFieldType(typeDef.ofType)): any);
return new GraphQLNonNull(extendFieldType(typeDef.ofType));
}
return getTypeFromDef(typeDef);
}
Expand Down
4 changes: 1 addition & 3 deletions src/utilities/findBreakingChanges.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ export function findFieldsThatChangedType(
// Check if the field's type has changed in the new schema.
const oldFieldType = getNamedType(oldTypeFieldsDef[fieldName].type);
const newFieldType = getNamedType(newTypeFieldsDef[fieldName].type);
if (oldFieldType &&
newFieldType &&
oldFieldType.name !== newFieldType.name) {
if (oldFieldType.name !== newFieldType.name) {
breakingFieldChanges.push({
type: BreakingChangeType.FIELD_CHANGED_KIND,
description: `${typeName}.${fieldName} changed type from ` +
Expand Down
8 changes: 2 additions & 6 deletions src/utilities/typeComparators.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {
} from '../type/definition';
import type {
GraphQLType,
GraphQLCompositeType,
GraphQLAbstractType
GraphQLCompositeType
} from '../type/definition';
import type {
GraphQLSchema
Expand Down Expand Up @@ -89,10 +88,7 @@ export function isTypeSubTypeOf(
// possible object type.
if (isAbstractType(superType) &&
maybeSubType instanceof GraphQLObjectType &&
schema.isPossibleType(
((superType: any): GraphQLAbstractType),
maybeSubType
)) {
schema.isPossibleType(superType, maybeSubType)) {
return true;
}

Expand Down
Loading

0 comments on commit 14caa05

Please sign in to comment.