[英]How to set type for Apollo resolver context?
我有一个简单的 Apollo GraphQL 子图,我想在其中为我的解析器中的上下文 arg 设置类型。
我创建了一个解析器并将上下文的类型设置如下:
interface Context {
dataSources: {
shopify: Shopify;
}
}
const server = new ApolloServer({
schema: buildSubgraphSchema({
typeDefs,
resolvers: {
Query: {
shop(_, _args, ctx: Context) {
console.log("ctx:", ctx)
},
}
}
}),
dataSources: () => ({
shopify: new Shopify()
})
});
但是,我设置的Context
接口似乎与我的解析器期望的类型不兼容,我收到以下错误:
Argument of type '{ typeDefs: any; resolvers: { Query: { shop(_: any, _args: any, ctx: Context): void; }; }; }' is not assignable to parameter of type 'DocumentNode | (GraphQLSchemaModule | DocumentNode)[] | LegacySchemaModule'.
Types of property 'resolvers' are incompatible.
Property 'Query' is incompatible with index signature.
Type '{ shop(_: any, _args: any, ctx: Context): void; }' is not assignable to type 'GraphQLScalarType<unknown, unknown> | { [enumValue: string]: string | number; } | { [fieldName: string]: GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<...>; }; }'.
Types of property 'shop' are incompatible.
Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'string | number | GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<any, unknown, any, unknown>; } | undefined'.
Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'GraphQLFieldResolver<any, unknown, any, unknown>'.
Types of parameters 'ctx' and 'context' are incompatible.
Type 'unknown' is not assignable to type 'Context'.ts(2345)
如何为我的解析器设置上下文类型,以便我可以访问接口和数据源等?
好的,我想我找到了更好的解决方案。
首先让我们真正了解buildSubgraphSchema
可以接受什么:
buildSubgraphSchema(
modulesOrSDL:
| (GraphQLSchemaModule | DocumentNode)[] //interesting...
| DocumentNode
| LegacySchemaModule, //our tried and true way
): GraphQLSchema
问题是我们试图传入一个LegacySchemaModule
( {typeDefs, resolvers}
) 但由于传入GraphQLResovlerMap
的<unknown>
泛型与显式定义的Context
产生了冲突
type LegacySchemaModule = {
typeDefs: DocumentNode | DocumentNode[];
resolvers?: GraphQLResolverMap<unknown>; //note `unknown`, the root of our typing errors
};
我们需要在解析器中实际作用于上下文的是一个GraphQLSchemaModule
定义如下:
export interface GraphQLSchemaModule {
typeDefs: DocumentNode;
resolvers?: GraphQLResolverMap<any>; //note the `any` here
}
因此,使用这样定义的解析器:
export const resolvers: GraphQLResolverMap<Context> = {
Query: {
shop(_, _args, ctx) {
console.log(ctx.datasources.shopify); // Shopify
},
},
};
我们现在可以传入(GraphQLSchemaModule | DocumentNode)[]
数组:
const server = new ApolloServer({
schema: buildSubgraphSchema([ //note the array
{
typeDefs, //DocumentNode
resolvers, //GraphQLSchemaModule, in this case GraphQLResolverMap<Context>
},
]),
});
这对我有用,没有 ts 错误,服务器启动得很好。 对社区的建议持开放态度,以获得更好的模式。
最终,我认为 codegen 工具旨在解决很多这些问题。 我现在正在研究这个: https://the-guild.dev/graphql/codegen
玩得开心!
ApolloServer
class 是通用的,您应该将自定义上下文指定为类型参数。 请参阅 文档和这些单元测试。
interface Context {
dataSources: {
shopify: Shopify;
}
}
const server = new ApolloServer<Context>({
// ^^^^^^^^^
schema: buildSubgraphSchema({
typeDefs,
resolvers: {
Query: {
shop(_, _args, ctx: Context) {
console.log("ctx:", ctx)
},
}
}
}),
dataSources: () => ({
shopify: new Shopify()
})
});
ApolloServer class 是通用的,您应该将自定义上下文指定为 > 类型参数。 请参阅文档和这些单元测试。
我也这么认为,但它仍然将其视为LegacySchemaModule
和 ts croaks ... 我上面更长的答案中的模式现在似乎是这样做的方式?
我尝试了您的代码,但与unknown
和Context
发生了相同类型的冲突:
error TS2345: Argument of type '{ typeDefs: DocumentNode; resolvers: { Query: { shop(_: any, _args: any, ctx: Context): void; }; }; }' is not assignable to parameter of type 'DocumentNode | (DocumentNode | GraphQLSchemaModule)[] | LegacySchemaModule'.
Types of property 'resolvers' are incompatible.
Property 'Query' is incompatible with index signature.
Type '{ shop(_: any, _args: any, ctx: Context): void; }' is not assignable to type 'GraphQLScalarType<unknown, unknown> | { [enumValue: string]: string | number; } | { [fieldName: string]: GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<...>; }; }'.
Types of property 'shop' are incompatible.
Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'string | number | GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<any, unknown, any, unknown>; } | undefined'.
Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'GraphQLFieldResolver<any, unknown, any, unknown>'.
Types of parameters 'ctx' and 'context' are incompatible.
>>>>>>>>> Type 'unknown' is not assignable to type 'Context'.
^^^^^^^^^ -- seems to originate in LegacySchemaModule because
we are pssing in {typeDefs,resolvers} as an object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.