Skip to content

Commit 3450c46

Browse files
committed
Add TContext to field resolvers
This adds additional type information to field resolvers, such that source and context get slightly more appropriate types. This partially improves one of the issues raised in #554
1 parent 1af8e9b commit 3450c46

File tree

8 files changed

+49
-49
lines changed

8 files changed

+49
-49
lines changed

src/execution/__tests__/mutations-test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,30 @@ const schema = new GraphQLSchema({
7979
immediatelyChangeTheNumber: {
8080
type: numberHolderType,
8181
args: { newNumber: { type: GraphQLInt } },
82-
resolve: (function (obj, { newNumber }) {
82+
resolve(obj, { newNumber }) {
8383
return obj.immediatelyChangeTheNumber(newNumber);
84-
}: any)
84+
}
8585
},
8686
promiseToChangeTheNumber: {
8787
type: numberHolderType,
8888
args: { newNumber: { type: GraphQLInt } },
89-
resolve: (function (obj, { newNumber }) {
89+
resolve(obj, { newNumber }) {
9090
return obj.promiseToChangeTheNumber(newNumber);
91-
}: any)
91+
}
9292
},
9393
failToChangeTheNumber: {
9494
type: numberHolderType,
9595
args: { newNumber: { type: GraphQLInt } },
96-
resolve: (function (obj, { newNumber }) {
96+
resolve(obj, { newNumber }) {
9797
return obj.failToChangeTheNumber(newNumber);
98-
}: any)
98+
}
9999
},
100100
promiseAndFailToChangeTheNumber: {
101101
type: numberHolderType,
102102
args: { newNumber: { type: GraphQLInt } },
103-
resolve: (function (obj, { newNumber }) {
103+
resolve(obj, { newNumber }) {
104104
return obj.promiseAndFailToChangeTheNumber(newNumber);
105-
}: any)
105+
}
106106
}
107107
},
108108
name: 'Mutation',

src/execution/execute.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,13 +626,13 @@ function resolveField(
626626

627627
// Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
628628
// function. Returns the result of resolveFn or the abrupt-return Error object.
629-
function resolveOrError(
629+
function resolveOrError<TSource, TContext>(
630630
exeContext: ExecutionContext,
631-
fieldDef: GraphQLField,
631+
fieldDef: GraphQLField<TSource, TContext>,
632632
fieldNode: FieldNode,
633-
resolveFn: GraphQLFieldResolver<*>,
634-
source: mixed,
635-
context: mixed,
633+
resolveFn: GraphQLFieldResolver<TSource, TContext>,
634+
source: TSource,
635+
context: TContext,
636636
info: GraphQLResolveInfo
637637
): Error | mixed {
638638
try {
@@ -1042,7 +1042,7 @@ function defaultResolveTypeFn(
10421042
* and returns it as the result, or if it's a function, returns the result
10431043
* of calling that function while passing along args and context.
10441044
*/
1045-
export const defaultFieldResolver: GraphQLFieldResolver<any> =
1045+
export const defaultFieldResolver: GraphQLFieldResolver<any, *> =
10461046
function (source, args, context, { fieldName }) {
10471047
// ensure source is a value for which property access is acceptable.
10481048
if (typeof source === 'object' || typeof source === 'function') {
@@ -1077,7 +1077,7 @@ function getFieldDef(
10771077
schema: GraphQLSchema,
10781078
parentType: GraphQLObjectType,
10791079
fieldName: string
1080-
): ?GraphQLField {
1080+
): ?GraphQLField<*, *> {
10811081
if (fieldName === SchemaMetaFieldDef.name &&
10821082
schema.getQueryType() === parentType) {
10831083
return SchemaMetaFieldDef;

src/execution/values.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function getVariableValues(
104104
* definitions and list of argument AST nodes.
105105
*/
106106
export function getArgumentValues(
107-
def: GraphQLField | GraphQLDirective,
107+
def: GraphQLField<*, *> | GraphQLDirective,
108108
node: FieldNode | DirectiveNode,
109109
variableValues?: ?{ [key: string]: mixed }
110110
): { [key: string]: mixed } {

src/type/definition.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,11 @@ export class GraphQLObjectType {
368368
description: ?string;
369369
isTypeOf: ?GraphQLIsTypeOfFn;
370370

371-
_typeConfig: GraphQLObjectTypeConfig<*>;
372-
_fields: GraphQLFieldMap;
371+
_typeConfig: GraphQLObjectTypeConfig<*, *>;
372+
_fields: GraphQLFieldMap<*, *>;
373373
_interfaces: Array<GraphQLInterfaceType>;
374374

375-
constructor(config: GraphQLObjectTypeConfig<*>) {
375+
constructor(config: GraphQLObjectTypeConfig<*, *>) {
376376
invariant(config.name, 'Type must be named.');
377377
assertValidName(config.name);
378378
this.name = config.name;
@@ -387,7 +387,7 @@ export class GraphQLObjectType {
387387
this._typeConfig = config;
388388
}
389389

390-
getFields(): GraphQLFieldMap {
390+
getFields(): GraphQLFieldMap<*, *> {
391391
return this._fields || (this._fields =
392392
defineFieldMap(this, this._typeConfig.fields)
393393
);
@@ -436,10 +436,10 @@ function defineInterfaces(
436436
return interfaces;
437437
}
438438

439-
function defineFieldMap(
439+
function defineFieldMap<TSource, TContext>(
440440
type: GraphQLNamedType,
441-
fieldsThunk: Thunk<GraphQLFieldConfigMap<*>>
442-
): GraphQLFieldMap {
441+
fieldsThunk: Thunk<GraphQLFieldConfigMap<TSource, TContext>>
442+
): GraphQLFieldMap<TSource, TContext> {
443443
const fieldMap = resolveThunk(fieldsThunk);
444444
invariant(
445445
isPlainObj(fieldMap),
@@ -507,10 +507,10 @@ function isPlainObj(obj) {
507507
return obj && typeof obj === 'object' && !Array.isArray(obj);
508508
}
509509

510-
export type GraphQLObjectTypeConfig<TSource> = {
510+
export type GraphQLObjectTypeConfig<TSource, TContext> = {
511511
name: string;
512512
interfaces?: Thunk<?Array<GraphQLInterfaceType>>;
513-
fields: Thunk<GraphQLFieldConfigMap<TSource>>;
513+
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>;
514514
isTypeOf?: ?GraphQLIsTypeOfFn;
515515
description?: ?string
516516
};
@@ -527,10 +527,10 @@ export type GraphQLIsTypeOfFn = (
527527
info: GraphQLResolveInfo
528528
) => boolean;
529529

530-
export type GraphQLFieldResolver<TSource> = (
530+
export type GraphQLFieldResolver<TSource, TContext> = (
531531
source: TSource,
532532
args: {[argName: string]: mixed},
533-
context: mixed,
533+
context: TContext,
534534
info: GraphQLResolveInfo
535535
) => mixed;
536536

@@ -549,10 +549,10 @@ export type GraphQLResolveInfo = {
549549

550550
export type ResponsePath = { prev: ResponsePath, key: string | number } | void;
551551

552-
export type GraphQLFieldConfig<TSource> = {
552+
export type GraphQLFieldConfig<TSource, TContext> = {
553553
type: GraphQLOutputType;
554554
args?: GraphQLFieldConfigArgumentMap;
555-
resolve?: GraphQLFieldResolver<TSource>;
555+
resolve?: GraphQLFieldResolver<TSource, TContext>;
556556
deprecationReason?: ?string;
557557
description?: ?string;
558558
};
@@ -567,16 +567,16 @@ export type GraphQLArgumentConfig = {
567567
description?: ?string;
568568
};
569569

570-
export type GraphQLFieldConfigMap<TSource> = {
571-
[fieldName: string]: GraphQLFieldConfig<TSource>;
570+
export type GraphQLFieldConfigMap<TSource, TContext> = {
571+
[fieldName: string]: GraphQLFieldConfig<TSource, TContext>;
572572
};
573573

574-
export type GraphQLField = {
574+
export type GraphQLField<TSource, TContext> = {
575575
name: string;
576576
description: ?string;
577577
type: GraphQLOutputType;
578578
args: Array<GraphQLArgument>;
579-
resolve?: GraphQLFieldResolver<*>;
579+
resolve?: GraphQLFieldResolver<TSource, TContext>;
580580
isDeprecated?: boolean;
581581
deprecationReason?: ?string;
582582
};
@@ -588,8 +588,8 @@ export type GraphQLArgument = {
588588
description?: ?string;
589589
};
590590

591-
export type GraphQLFieldMap = {
592-
[fieldName: string]: GraphQLField;
591+
export type GraphQLFieldMap<TSource, TContext> = {
592+
[fieldName: string]: GraphQLField<TSource, TContext>;
593593
};
594594

595595

@@ -617,10 +617,10 @@ export class GraphQLInterfaceType {
617617
description: ?string;
618618
resolveType: ?GraphQLTypeResolver;
619619

620-
_typeConfig: GraphQLInterfaceTypeConfig;
621-
_fields: GraphQLFieldMap;
620+
_typeConfig: GraphQLInterfaceTypeConfig<*, *>;
621+
_fields: GraphQLFieldMap<*, *>;
622622

623-
constructor(config: GraphQLInterfaceTypeConfig) {
623+
constructor(config: GraphQLInterfaceTypeConfig<*, *>) {
624624
invariant(config.name, 'Type must be named.');
625625
assertValidName(config.name);
626626
this.name = config.name;
@@ -635,7 +635,7 @@ export class GraphQLInterfaceType {
635635
this._typeConfig = config;
636636
}
637637

638-
getFields(): GraphQLFieldMap {
638+
getFields(): GraphQLFieldMap<*, *> {
639639
return this._fields ||
640640
(this._fields = defineFieldMap(this, this._typeConfig.fields));
641641
}
@@ -645,9 +645,9 @@ export class GraphQLInterfaceType {
645645
}
646646
}
647647

648-
export type GraphQLInterfaceTypeConfig = {
648+
export type GraphQLInterfaceTypeConfig<TSource, TContext> = {
649649
name: string,
650-
fields: Thunk<GraphQLFieldConfigMap<mixed>>,
650+
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>,
651651
/**
652652
* Optionally provide a custom type resolver function. If one is not provided,
653653
* the default implementation will call `isTypeOf` on each implementing

src/type/introspection.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,15 @@ export const __TypeKind = new GraphQLEnumType({
418418
* so the format for args is different.
419419
*/
420420

421-
export const SchemaMetaFieldDef: GraphQLField = {
421+
export const SchemaMetaFieldDef: GraphQLField<*, *> = {
422422
name: '__schema',
423423
type: new GraphQLNonNull(__Schema),
424424
description: 'Access the current type schema of this server.',
425425
args: [],
426426
resolve: (source, args, context, { schema }) => schema
427427
};
428428

429-
export const TypeMetaFieldDef: GraphQLField = {
429+
export const TypeMetaFieldDef: GraphQLField<*, *> = {
430430
name: '__type',
431431
type: __Type,
432432
description: 'Request the type information of a single type.',
@@ -437,7 +437,7 @@ export const TypeMetaFieldDef: GraphQLField = {
437437
schema.getType(((name: any): string))
438438
};
439439

440-
export const TypeNameMetaFieldDef: GraphQLField = {
440+
export const TypeNameMetaFieldDef: GraphQLField<*, *> = {
441441
name: '__typename',
442442
type: new GraphQLNonNull(GraphQLString),
443443
description: 'The name of the current Object type at runtime.',

src/utilities/TypeInfo.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class TypeInfo {
4949
_typeStack: Array<?GraphQLOutputType>;
5050
_parentTypeStack: Array<?GraphQLCompositeType>;
5151
_inputTypeStack: Array<?GraphQLInputType>;
52-
_fieldDefStack: Array<?GraphQLField>;
52+
_fieldDefStack: Array<?GraphQLField<*, *>>;
5353
_directive: ?GraphQLDirective;
5454
_argument: ?GraphQLArgument;
5555
_getFieldDef: typeof getFieldDef;
@@ -89,7 +89,7 @@ export class TypeInfo {
8989
}
9090
}
9191

92-
getFieldDef(): ?GraphQLField {
92+
getFieldDef(): ?GraphQLField<*, *> {
9393
if (this._fieldDefStack.length > 0) {
9494
return this._fieldDefStack[this._fieldDefStack.length - 1];
9595
}
@@ -226,7 +226,7 @@ function getFieldDef(
226226
schema: GraphQLSchema,
227227
parentType: GraphQLType,
228228
fieldNode: FieldNode
229-
): ?GraphQLField {
229+
): ?GraphQLField<*, *> {
230230
const name = fieldNode.name.value;
231231
if (name === SchemaMetaFieldDef.name &&
232232
schema.getQueryType() === parentType) {

src/validation/rules/OverlappingFieldsCanBeMerged.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ type ConflictReason = [ string, ConflictReasonMessage ];
9898
// Reason is a string, or a nested list of conflicts.
9999
type ConflictReasonMessage = string | Array<ConflictReason>;
100100
// Tuple defining a field node in a context.
101-
type NodeAndDef = [ GraphQLCompositeType, FieldNode, ?GraphQLField ];
101+
type NodeAndDef = [ GraphQLCompositeType, FieldNode, ?GraphQLField<*, *> ];
102102
// Map of array of those.
103103
type NodeAndDefCollection = { [key: string]: Array<NodeAndDef> };
104104

src/validation/validate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ export class ValidationContext {
240240
return this._typeInfo.getInputType();
241241
}
242242

243-
getFieldDef(): ?GraphQLField {
243+
getFieldDef(): ?GraphQLField<*, *> {
244244
return this._typeInfo.getFieldDef();
245245
}
246246

0 commit comments

Comments
 (0)