From b22ef58474a6aa4f3f920f048cdd4e7cc1731401 Mon Sep 17 00:00:00 2001 From: iamchenxin Date: Fri, 8 Jul 2016 00:10:52 -0600 Subject: [PATCH 1/2] make GraphQLFieldResolveFn to GraphQLFieldResolveFn --- src/__tests__/starWarsData.js | 50 +++++++++++++++++++++++++++++---- src/__tests__/starWarsSchema.js | 15 ++++++---- src/execution/execute.js | 2 +- src/type/definition.js | 8 +++--- 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/__tests__/starWarsData.js b/src/__tests__/starWarsData.js index 59f0857727..2da601c65a 100644 --- a/src/__tests__/starWarsData.js +++ b/src/__tests__/starWarsData.js @@ -1,10 +1,12 @@ +/* @flow */ +/* eslint quote-props: ["error", "as-needed", +{ "keywords": true, "unnecessary": false }]*/ /** * Copyright (c) 2015, Facebook, Inc. * All rights reserved. * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ - /** * This defines a basic set of data for our Star Wars Schema. * @@ -13,6 +15,8 @@ * JSON objects in a more complex demo. */ +import invariant from '../jsutils/invariant'; + const luke = { id: '1000', name: 'Luke Skywalker', @@ -80,10 +84,38 @@ const droidData = { '2001': artoo, }; +/** + * These are data types corresponding to the schema design. + * They represent what the input and output datas should be + * in schema's resolving hierarchy. + * If the schema is re-designed,these types should be re-designed too. + */ +export type Character = { + id: string, + name?: string, + friends?: Array, + appearsIn?: Array, +}; + +export type Human = { + id: string, + name?: string, + friends?: Array, + appearsIn?: Array, + homePlanet?: string, +}; + +export type Droid = { + id: string, + name?: string, + friends?: Array, + appearsIn?: Array, + primaryFunction?: string +}; /** * Helper function to get a character by ID. */ -function getCharacter(id) { +function getCharacter(id): Promise<*> { // Returning a promise just to illustrate GraphQL.js's support. return Promise.resolve(humanData[id] || droidData[id]); } @@ -91,14 +123,20 @@ function getCharacter(id) { /** * Allows us to query for a character's friends. */ -export function getFriends(character) { +export function getFriends(character: Character): Array<*> { + // as you can see,with Flow + // If you choose a schema structure like {friends?: Array<*>}. + // You must check it ,or re-design your schema. + // Flow will keep you away from hiden bugs. + invariant(character.friends !== undefined, + 'Character.friends should not be undefined'); return character.friends.map(id => getCharacter(id)); } /** * Allows us to fetch the undisputed hero of the Star Wars trilogy, R2-D2. */ -export function getHero(episode) { +export function getHero(episode: number): Character { if (episode === 5) { // Luke is the hero of Episode V. return luke; @@ -110,13 +148,13 @@ export function getHero(episode) { /** * Allows us to query for the human with the given id. */ -export function getHuman(id) { +export function getHuman(id: string): Human { return humanData[id]; } /** * Allows us to query for the droid with the given id. */ -export function getDroid(id) { +export function getDroid(id: string): Droid { return droidData[id]; } diff --git a/src/__tests__/starWarsSchema.js b/src/__tests__/starWarsSchema.js index 0c9c34b637..b93b545043 100644 --- a/src/__tests__/starWarsSchema.js +++ b/src/__tests__/starWarsSchema.js @@ -1,3 +1,4 @@ +/* @flow */ /** * Copyright (c) 2015, Facebook, Inc. * All rights reserved. @@ -19,6 +20,8 @@ import { import { getFriends, getHero, getHuman, getDroid } from './starWarsData.js'; +import type {Character, Human, Droid} from './starWarsData.js'; + /** * This is designed to be an end-to-end test, demonstrating * the full GraphQL stack. @@ -132,7 +135,7 @@ const characterInterface = new GraphQLInterfaceType({ }, }), resolveType: character => { - return getHuman(character.id) ? humanType : droidType; + return getHuman((character: any).id) ? humanType : droidType; } }); @@ -164,7 +167,7 @@ const humanType = new GraphQLObjectType({ type: new GraphQLList(characterInterface), description: 'The friends of the human, or an empty list if they ' + 'have none.', - resolve: human => getFriends(human), + resolve: (human: Human): Array> => getFriends(human), }, appearsIn: { type: new GraphQLList(episodeEnum), @@ -214,7 +217,7 @@ const droidType = new GraphQLObjectType({ type: new GraphQLList(characterInterface), description: 'The friends of the droid, or an empty list if they ' + 'have none.', - resolve: droid => getFriends(droid), + resolve: (droid: Droid): Array> => getFriends(droid), }, appearsIn: { type: new GraphQLList(episodeEnum), @@ -261,7 +264,7 @@ const queryType = new GraphQLObjectType({ type: episodeEnum } }, - resolve: (root, { episode }) => getHero(episode), + resolve: (root, { episode }): Character => getHero((episode: any)), }, human: { type: humanType, @@ -271,7 +274,7 @@ const queryType = new GraphQLObjectType({ type: new GraphQLNonNull(GraphQLString) } }, - resolve: (root, { id }) => getHuman(id), + resolve: (root, { id }): Human => getHuman((id: any)), }, droid: { type: droidType, @@ -281,7 +284,7 @@ const queryType = new GraphQLObjectType({ type: new GraphQLNonNull(GraphQLString) } }, - resolve: (root, { id }) => getDroid(id), + resolve: (root, { id }): Droid => getDroid((id: any)), }, }) }); diff --git a/src/execution/execute.js b/src/execution/execute.js index 6a5ae81c40..2312a29351 100644 --- a/src/execution/execute.js +++ b/src/execution/execute.js @@ -596,7 +596,7 @@ function resolveField( // Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField` // function. Returns the result of resolveFn or the abrupt-return Error object. function resolveOrError( - resolveFn: GraphQLFieldResolveFn<*>, + resolveFn: GraphQLFieldResolveFn<*, *>, source: mixed, args: { [key: string]: mixed }, context: mixed, diff --git a/src/type/definition.js b/src/type/definition.js index 11d3bb688f..d8ddbac7c7 100644 --- a/src/type/definition.js +++ b/src/type/definition.js @@ -478,12 +478,12 @@ export type GraphQLIsTypeOfFn = ( info: GraphQLResolveInfo ) => boolean -export type GraphQLFieldResolveFn = ( +export type GraphQLFieldResolveFn = ( source: TSource, args: {[argName: string]: mixed}, context: mixed, info: GraphQLResolveInfo -) => mixed +) => TResult export type GraphQLResolveInfo = { fieldName: string; @@ -501,7 +501,7 @@ export type GraphQLResolveInfo = { export type GraphQLFieldConfig = { type: GraphQLOutputType; args?: GraphQLFieldConfigArgumentMap; - resolve?: GraphQLFieldResolveFn; + resolve?: GraphQLFieldResolveFn; deprecationReason?: ?string; description?: ?string; } @@ -525,7 +525,7 @@ export type GraphQLFieldDefinition = { description: ?string; type: GraphQLOutputType; args: Array; - resolve?: GraphQLFieldResolveFn<*>; + resolve?: GraphQLFieldResolveFn<*, *>; deprecationReason?: ?string; } From 784cd09dcee5fcd06b35cc3273265516db05c346 Mon Sep 17 00:00:00 2001 From: iamchenxin Date: Mon, 25 Jul 2016 08:37:44 -0600 Subject: [PATCH 2/2] amend code style --- src/__tests__/starWarsData.js | 6 ++---- src/__tests__/starWarsSchema.js | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/__tests__/starWarsData.js b/src/__tests__/starWarsData.js index 2da601c65a..0fa95af851 100644 --- a/src/__tests__/starWarsData.js +++ b/src/__tests__/starWarsData.js @@ -1,6 +1,4 @@ /* @flow */ -/* eslint quote-props: ["error", "as-needed", -{ "keywords": true, "unnecessary": false }]*/ /** * Copyright (c) 2015, Facebook, Inc. * All rights reserved. @@ -115,7 +113,7 @@ export type Droid = { /** * Helper function to get a character by ID. */ -function getCharacter(id): Promise<*> { +function getCharacter(id) { // Returning a promise just to illustrate GraphQL.js's support. return Promise.resolve(humanData[id] || droidData[id]); } @@ -123,7 +121,7 @@ function getCharacter(id): Promise<*> { /** * Allows us to query for a character's friends. */ -export function getFriends(character: Character): Array<*> { +export function getFriends(character: Character): Array> { // as you can see,with Flow // If you choose a schema structure like {friends?: Array<*>}. // You must check it ,or re-design your schema. diff --git a/src/__tests__/starWarsSchema.js b/src/__tests__/starWarsSchema.js index b93b545043..9f0c0e3956 100644 --- a/src/__tests__/starWarsSchema.js +++ b/src/__tests__/starWarsSchema.js @@ -20,7 +20,7 @@ import { import { getFriends, getHero, getHuman, getDroid } from './starWarsData.js'; -import type {Character, Human, Droid} from './starWarsData.js'; +import type { Character, Human, Droid } from './starWarsData.js'; /** * This is designed to be an end-to-end test, demonstrating