apollo-tooling
apollo-tooling copied to clipboard
Incomplete (and duplicate) GraphQLResolverMap typings
Intended outcome:
GraphQLResolverMap
should accept enum
and scalars. The following resolver should not produce any TypeScript error:
enum SomeEnum {
FOO = "foo",
BAR = "bar",
}
const AnotherEnum = {
FOO: "foo",
BAR: "bar",
};
const resolvers: GraphQLResolverMap<any> = {
SomeEnum,
AnotherEnum,
};
Actual outcome:
Works fine when using GraphQLResolverMap
from apollo-graphql
but does not when importing from @apollographql/apollo-tools
.
GraphQLResolverMap
is defined within apollo-graphql
and @apollographql/apollo-tools
but the definitions are not the same.
// apollo-graphql/src/schema/resolverMap.ts
export interface GraphQLResolverMap<TContext = {}> {
[typeName: string]:
| {
[fieldName: string]:
| GraphQLFieldResolver<any, TContext>
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
};
}
| GraphQLScalarType
| {
[enumValue: string]: string | number;
};
}
// apollo-tools/src/schema/resolverMap.ts
export interface GraphQLResolverMap<TContext> {
[typeName: string]: {
[fieldName: string]:
| GraphQLFieldResolver<any, TContext>
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
subscribe?: undefined;
}
| {
requires?: string;
resolve?: undefined;
subscribe: GraphQLFieldResolver<any, TContext>;
}
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
subscribe: GraphQLFieldResolver<any, TContext>;
};
};
}
This is problematic since apollo-server
uses the definitions from @apollographql/apollo-tools
to type modules
config parameter.
How to reproduce the issue:
import {
GraphQLResolverMap,
} from "apollo-graphql";
import {
GraphQLResolverMap as GraphQLResolverMap_,
} from "@apollographql/apollo-tools";
enum SomeEnum {
FOO = "foo",
BAR = "bar",
}
const AnotherEnum = {
FOO: "foo",
BAR: "bar",
};
const resolvers1: GraphQLResolverMap<any> = {
SomeEnum,
AnotherEnum,
};
const resolvers2: GraphQLResolverMap_<any> = {
SomeEnum,
AnotherEnum,
};
Versions
-
@apollographql/apollo-tools
: 0.4.1 -
apollo-graphql
: 4.0.0
The actual apollo server config references IResolvers.
https://github.com/apollographql/apollo-server/blob/master/packages/apollo-server-core/src/types.ts#L98
So I guess that the tools should really be using this:
https://github.com/apollographql/graphql-tools/blob/master/src/Interfaces.ts#L97
There should be no reason why the GraphQLSchemaModule goes off-piste and makes it's own type, especially as the Schema Module is essentially a composed type of two pre existing types
Having the same problem except with calls to buildSubgraphSchema
, it's parameter is a GraphQLSchemaModule
which is defined in @apollo/subgraph
and references it's own version of GraphQLResolverMap
.
@apollo/subgraph/src/schema-helper/resolverMap.ts
import { GraphQLFieldResolver, GraphQLScalarType, DocumentNode } from 'graphql';
export interface GraphQLSchemaModule {
typeDefs: DocumentNode;
resolvers?: GraphQLResolverMap<any>;
}
// eslint-disable-next-line @typescript-eslint/ban-types
export interface GraphQLResolverMap<TContext = {}> {
[typeName: string]:
| {
[fieldName: string]:
| GraphQLFieldResolver<any, TContext>
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
};
}
| GraphQLScalarType
| {
[enumValue: string]: string | number;
};
}
The other GraphQLSchemaModule
is defined here
@apollographql/apollo-tools/src/buildServiceDefinition.ts
// ...
import { GraphQLResolverMap } from "./schema/resolverMap";
// ...
export interface GraphQLSchemaModule {
typeDefs: DocumentNode;
resolvers?: GraphQLResolverMap<any>;
}
// ...
@apollographql/apollo-tools/src/schema/resolverMap.ts
import { GraphQLFieldResolver } from "graphql";
export interface GraphQLResolverMap<TContext> {
[typeName: string]: {
[fieldName: string]:
| GraphQLFieldResolver<any, TContext>
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
subscribe?: undefined;
}
| {
requires?: string;
resolve?: undefined;
subscribe: GraphQLFieldResolver<any, TContext>;
}
| {
requires?: string;
resolve: GraphQLFieldResolver<any, TContext>;
subscribe: GraphQLFieldResolver<any, TContext>;
};
};
}
Anyone have a suitable workaround? Is the Apollo team working on this?