Skip to content

Commit

Permalink
feat: convert Thunk to ThunkArray and ThunkObjMap (#2955)
Browse files Browse the repository at this point in the history
  • Loading branch information
saihaj committed Mar 13, 2021
1 parent 789a98a commit 3e916ef
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 31 deletions.
3 changes: 2 additions & 1 deletion src/index.d.ts
Expand Up @@ -137,7 +137,8 @@ export {
GraphQLWrappingType,
GraphQLNullableType,
GraphQLNamedType,
Thunk,
ThunkArray,
ThunkObjMap,
GraphQLSchemaConfig,
GraphQLSchemaExtensions,
GraphQLDirectiveConfig,
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Expand Up @@ -136,7 +136,8 @@ export type {
GraphQLWrappingType,
GraphQLNullableType,
GraphQLNamedType,
Thunk,
ThunkArray,
ThunkObjMap,
GraphQLSchemaConfig,
GraphQLDirectiveConfig,
GraphQLArgument,
Expand Down
7 changes: 7 additions & 0 deletions src/jsutils/ObjMap.d.ts
@@ -0,0 +1,7 @@
export type ObjMap<T> = Record<string, T>;
export type ObjMapLike<T> = ObjMap<T> | Record<string, T>;

export type ReadOnlyObjMap<T> = Readonly<Record<string, T>>;
export type ReadOnlyObjMapLike<T> =
| Readonly<Record<string, T>>
| ReadOnlyObjMap<T>;
18 changes: 9 additions & 9 deletions src/type/definition.d.ts
Expand Up @@ -5,6 +5,7 @@ import { Maybe } from '../jsutils/Maybe';

import { PromiseOrValue } from '../jsutils/PromiseOrValue';
import { Path } from '../jsutils/Path';
import { ObjMap } from '../jsutils/ObjMap';

import {
ScalarTypeDefinitionNode,
Expand Down Expand Up @@ -263,9 +264,8 @@ export function getNamedType(type: GraphQLType): GraphQLNamedType;
* Used while defining GraphQL types to allow for circular references in
* otherwise immutable type definitions.
*/
export type Thunk<T extends { [key: string]: any } | Array<any>> =
| (() => T)
| T;
export type ThunkArray<T> = Array<T> | (() => Array<T>);
export type ThunkObjMap<T> = ObjMap<T> | (() => ObjMap<T>);

/**
* Custom extensions
Expand Down Expand Up @@ -435,8 +435,8 @@ export function argsToArgsConfig(
export interface GraphQLObjectTypeConfig<TSource, TContext> {
name: string;
description?: Maybe<string>;
interfaces?: Thunk<Array<GraphQLInterfaceType>>;
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>;
interfaces?: ThunkArray<GraphQLInterfaceType>;
fields: ThunkObjMap<GraphQLFieldConfig<TSource, TContext>>;
isTypeOf?: Maybe<GraphQLIsTypeOfFn<TSource, TContext>>;
extensions?: Maybe<Readonly<GraphQLObjectTypeExtensions<TSource, TContext>>>;
astNode?: Maybe<ObjectTypeDefinitionNode>;
Expand Down Expand Up @@ -637,8 +637,8 @@ export class GraphQLInterfaceType {
export interface GraphQLInterfaceTypeConfig<TSource, TContext> {
name: string;
description?: Maybe<string>;
interfaces?: Thunk<Array<GraphQLInterfaceType>>;
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>;
interfaces?: ThunkArray<GraphQLInterfaceType>;
fields: ThunkObjMap<GraphQLFieldConfig<TSource, TContext>>;
/**
* Optionally provide a custom type resolver function. If one is not provided,
* the default implementation will call `isTypeOf` on each implementing
Expand Down Expand Up @@ -711,7 +711,7 @@ export class GraphQLUnionType {
export interface GraphQLUnionTypeConfig<TSource, TContext> {
name: string;
description?: Maybe<string>;
types: Thunk<Array<GraphQLObjectType>>;
types: ThunkArray<GraphQLObjectType>;
/**
* Optionally provide a custom type resolver function. If one is not provided,
* the default implementation will call `isTypeOf` on each implementing
Expand Down Expand Up @@ -884,7 +884,7 @@ export class GraphQLInputObjectType {
export interface GraphQLInputObjectTypeConfig {
name: string;
description?: Maybe<string>;
fields: Thunk<GraphQLInputFieldConfigMap>;
fields: ThunkObjMap<GraphQLInputFieldConfig>;
extensions?: Maybe<Readonly<GraphQLInputObjectTypeExtensions>>;
astNode?: Maybe<InputObjectTypeDefinitionNode>;
extensionASTNodes?: Maybe<ReadonlyArray<InputObjectTypeExtensionNode>>;
Expand Down
41 changes: 23 additions & 18 deletions src/type/definition.js
Expand Up @@ -511,9 +511,14 @@ export function getNamedType(type) {
* Used while defining GraphQL types to allow for circular references in
* otherwise immutable type definitions.
*/
export type Thunk<+T: ObjMap<any> | Array<any>> = (() => T) | T;
export type ThunkArray<T> = (() => Array<T>) | Array<T>;
export type ThunkObjMap<T> = (() => ObjMap<T>) | ObjMap<T>;

function resolveThunk<+T: ObjMap<any> | Array<any>>(thunk: Thunk<T>): T {
function resolveArrayThunk<T>(thunk: ThunkArray<T>): Array<T> {
return typeof thunk === 'function' ? thunk() : thunk;
}

function resolveObjMapThunk<T>(thunk: ThunkObjMap<T>): ObjMap<T> {
return typeof thunk === 'function' ? thunk() : thunk;
}

Expand Down Expand Up @@ -703,8 +708,8 @@ export class GraphQLObjectType {
astNode: ?ObjectTypeDefinitionNode;
extensionASTNodes: ?$ReadOnlyArray<ObjectTypeExtensionNode>;

_fields: Thunk<GraphQLFieldMap<any, any>>;
_interfaces: Thunk<Array<GraphQLInterfaceType>>;
_fields: ThunkObjMap<GraphQLField<any, any>>;
_interfaces: ThunkArray<GraphQLInterfaceType>;

constructor(config: $ReadOnly<GraphQLObjectTypeConfig<any, any>>) {
this.name = config.name;
Expand Down Expand Up @@ -771,7 +776,7 @@ function defineInterfaces(
| GraphQLInterfaceTypeConfig<mixed, mixed>,
>,
): Array<GraphQLInterfaceType> {
const interfaces = resolveThunk(config.interfaces ?? []);
const interfaces = resolveArrayThunk(config.interfaces ?? []);
devAssert(
Array.isArray(interfaces),
`${config.name} interfaces must be an Array or a function which returns an Array.`,
Expand All @@ -785,7 +790,7 @@ function defineFieldMap<TSource, TContext>(
| GraphQLInterfaceTypeConfig<TSource, TContext>,
>,
): GraphQLFieldMap<TSource, TContext> {
const fieldMap = resolveThunk(config.fields);
const fieldMap = resolveObjMapThunk(config.fields);
devAssert(
isPlainObj(fieldMap),
`${config.name} fields must be an object with field names as keys or a function which returns such an object.`,
Expand Down Expand Up @@ -874,8 +879,8 @@ export function argsToArgsConfig(
export type GraphQLObjectTypeConfig<TSource, TContext> = {|
name: string,
description?: ?string,
interfaces?: Thunk<Array<GraphQLInterfaceType>>,
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>,
interfaces?: ThunkArray<GraphQLInterfaceType>,
fields: ThunkObjMap<GraphQLFieldConfig<TSource, TContext>>,
isTypeOf?: ?GraphQLIsTypeOfFn<TSource, TContext>,
extensions?: ?ReadOnlyObjMapLike<mixed>,
astNode?: ?ObjectTypeDefinitionNode,
Expand Down Expand Up @@ -1020,8 +1025,8 @@ export class GraphQLInterfaceType {
astNode: ?InterfaceTypeDefinitionNode;
extensionASTNodes: ?$ReadOnlyArray<InterfaceTypeExtensionNode>;

_fields: Thunk<GraphQLFieldMap<any, any>>;
_interfaces: Thunk<Array<GraphQLInterfaceType>>;
_fields: ThunkObjMap<GraphQLField<any, any>>;
_interfaces: ThunkArray<GraphQLInterfaceType>;

constructor(config: $ReadOnly<GraphQLInterfaceTypeConfig<any, any>>) {
this.name = config.name;
Expand Down Expand Up @@ -1085,8 +1090,8 @@ export class GraphQLInterfaceType {
export type GraphQLInterfaceTypeConfig<TSource, TContext> = {|
name: string,
description?: ?string,
interfaces?: Thunk<Array<GraphQLInterfaceType>>,
fields: Thunk<GraphQLFieldConfigMap<TSource, TContext>>,
interfaces?: ThunkArray<GraphQLInterfaceType>,
fields: ThunkObjMap<GraphQLFieldConfig<TSource, TContext>>,
/**
* Optionally provide a custom type resolver function. If one is not provided,
* the default implementation will call `isTypeOf` on each implementing
Expand Down Expand Up @@ -1137,7 +1142,7 @@ export class GraphQLUnionType {
astNode: ?UnionTypeDefinitionNode;
extensionASTNodes: ?$ReadOnlyArray<UnionTypeExtensionNode>;

_types: Thunk<Array<GraphQLObjectType>>;
_types: ThunkArray<GraphQLObjectType>;

constructor(config: $ReadOnly<GraphQLUnionTypeConfig<any, any>>) {
this.name = config.name;
Expand Down Expand Up @@ -1192,7 +1197,7 @@ export class GraphQLUnionType {
function defineTypes(
config: $ReadOnly<GraphQLUnionTypeConfig<mixed, mixed>>,
): Array<GraphQLObjectType> {
const types = resolveThunk(config.types);
const types = resolveArrayThunk(config.types);
devAssert(
Array.isArray(types),
`Must provide Array of types or a function which returns such an array for Union ${config.name}.`,
Expand All @@ -1203,7 +1208,7 @@ function defineTypes(
export type GraphQLUnionTypeConfig<TSource, TContext> = {|
name: string,
description?: ?string,
types: Thunk<Array<GraphQLObjectType>>,
types: ThunkArray<GraphQLObjectType>,
/**
* Optionally provide a custom type resolver function. If one is not provided,
* the default implementation will call `isTypeOf` on each implementing
Expand Down Expand Up @@ -1463,7 +1468,7 @@ export class GraphQLInputObjectType {
astNode: ?InputObjectTypeDefinitionNode;
extensionASTNodes: ?$ReadOnlyArray<InputObjectTypeExtensionNode>;

_fields: Thunk<GraphQLInputFieldMap>;
_fields: ThunkObjMap<GraphQLInputField>;

constructor(config: $ReadOnly<GraphQLInputObjectTypeConfig>) {
this.name = config.name;
Expand Down Expand Up @@ -1519,7 +1524,7 @@ export class GraphQLInputObjectType {
function defineInputFieldMap(
config: $ReadOnly<GraphQLInputObjectTypeConfig>,
): GraphQLInputFieldMap {
const fieldMap = resolveThunk(config.fields);
const fieldMap = resolveObjMapThunk(config.fields);
devAssert(
isPlainObj(fieldMap),
`${config.name} fields must be an object with field names as keys or a function which returns such an object.`,
Expand All @@ -1545,7 +1550,7 @@ function defineInputFieldMap(
export type GraphQLInputObjectTypeConfig = {|
name: string,
description?: ?string,
fields: Thunk<GraphQLInputFieldConfigMap>,
fields: ThunkObjMap<GraphQLInputFieldConfig>,
extensions?: ?ReadOnlyObjMapLike<mixed>,
astNode?: ?InputObjectTypeDefinitionNode,
extensionASTNodes?: ?$ReadOnlyArray<InputObjectTypeExtensionNode>,
Expand Down
3 changes: 2 additions & 1 deletion src/type/index.d.ts
Expand Up @@ -73,7 +73,8 @@ export {
GraphQLWrappingType,
GraphQLNullableType,
GraphQLNamedType,
Thunk,
ThunkArray,
ThunkObjMap,
GraphQLArgument,
GraphQLArgumentConfig,
GraphQLArgumentExtensions,
Expand Down
3 changes: 2 additions & 1 deletion src/type/index.js
Expand Up @@ -128,7 +128,8 @@ export type {
GraphQLWrappingType,
GraphQLNullableType,
GraphQLNamedType,
Thunk,
ThunkArray,
ThunkObjMap,
GraphQLArgument,
GraphQLArgumentConfig,
GraphQLEnumTypeConfig,
Expand Down

0 comments on commit 3e916ef

Please sign in to comment.