typescript - GraphQLServer 聯合類型 "抽象類型 N 必須在運行時解析為物件類型" 錯誤
給定一個 GraphQL union 返回類型:
union GetBankAccountsResponseOrUserInputRequest = GetAccountsResponse | UserInputRequest
應由給定的解析器返回:
type Query {
getBankAccounts: GetBankAccountsResponseOrUserInputRequest!
}
我收到這些關於 __resolveType 或 __isTypeOf 函數的警告或錯誤:
Abstract type N must resolve to an Object type at runtime for field Query.getBankAccounts with value { ..., __isTypeOf: [function __isTypeOf] }, received "undefined". Either the N type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.'
我已經在 GitHub 的議題和 Stack Overflow 的問題中搜尋了好幾天,尋找解決這個錯誤的方法。
在我的解析器中實作 __resolveType 或 __isTypeOf 並不起作用:
export const Query = {
getBankAccounts: (parent, args, context: IContext, info) => {
return {
__isTypeOf(obj) { // OR __resolveType, none of them work
return `GetAccountsResponse`;
},
accounts: []
};
},
};
答案#1
由於在我的解析器中實作 __resolveType 或 __isTypeOf 對我無效,我最後通過直接將 __typename 添加到解析器返回的物件中來解決這個問題。
在 getBankAccounts 解析器實現中:
async getBankAccounts(): GetBankAccountsResponseOrUserInputRequest {
if (shouldGetUserInputRequest()) {
return {
__typename: "UserInputRequest",
...response,
};
}
return {
__typename: "GetAccountsResponse",
accounts,
};
}
希望這能幫助到某人。
答案#2
您的解析器映射設置不正確。
傳遞給 ApolloServer(或 makeExecutableSchema)的解析器映射應該是一個對象,其鍵是您架構中的類型名稱,每個鍵對應到另一個對象,該對象的鍵是該類型的欄位名稱。每個欄位名稱然後對應到一個解析函數。
const resolvers = {
SomeType: {
someField: (parent, args, context, info) => { ... },
},
}
您使用相同的解析器映射來傳入聯合類型或介面的 resolveType 函數。模式是相同的,但類型名稱是聯合類型或介面的名稱,而不是欄位名稱,鍵是 __resolveType:
const resolvers = {
SomeType: {
someField: (parent, args, context, info) => { ... },
},
SomeUnion: {
__resolveType: (parent) => { ... },
}
}
resolveType 函數應該總是返回一個與您的架構中現有物件類型名稱相符的字串。
如果你使用 __isTypeOf 而不是 __resolveType,那麼情況會略有不同,因為 isTypeOf 函數是與特定物件類型相關聯的,而不是接口或聯合類型。這些都在文檔中有所說明。所以解析器映射看起來是這樣的:
const resolvers = {
SomeType: {
someField: (parent, args, context, info) => { ... },
__isTypeOf: (parent) => { ... },
},
}
__isTypeOf 應該總是返回 true 或 false,取決於傳入的物件是否確實屬於該類型。
你只需要使用 __resolveType 或 __isTypeOf 其中之一。如果你使用 __isTypeOf,你必須將它添加到聯合類型或介面中的每一個可能的對象類型。
