[英]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.