【发布时间】:2021-01-20 18:51:56
【问题描述】:
我正在使用 Typescript 构建 Apollo GraphQL 服务器,但无法理解在类型系统中处理事物的正确方法。尽管 GraphQL 和 Apollo 是代码的一部分,但我特别想知道 TypeScript 部分。我也很难理解接口与类型的作用以及每种类型的最佳实践是什么(即,您何时使用类型与接口,如何处理扩展它们等)。
我的大部分不明确之处在于解析器。我将在我询问的相关部分旁边的代码中散布 cmets 和问题。再次感谢您提供的任何帮助:
type BankingAccount = {
id: string;
type: string;
attributes: SpendingAccountAttributes | SavingsAccountAttributes
}
// I've realized this "SpendingAccountAttributes | SavingsAccountAttributes" is the wrong way
// to do what I'm trying to do. I essentially want to the tell the
// type system that this can be one or the other. As I understand it, the way it is written
// will create a Union, returning only the fields that are shared between both types, in this
// case what is essentially in the `BankingAttributes` type. Is that correct?
interface BankingAttributes = {
routingNumber: string;
accountNumber: string;
balance: number;
fundsAvailable: number;
}
// Is it better to remove the `SpendingAccountAttributes` and `SavingsAccountAttribute` specific
// types and just leave them as optional types on the `BankingAttributes`. I will
// in time be creating a resolver for the `SpendingAccount` and `SavingAccount` as standalone
// queries so it seems useful to have them. Not sure though
interface SpendingAccountAttributes extends BankingAttributes {
defaultPaymentCardId: string;
defaultPaymentCardLastFour: string;
accountFeatures: Record<string, unknown>;
}
interface SavingsAccountAttributes extends BankingAttributes {
interestRate: number;
interestRateYTD: number;
}
// Mixing types and interfaces seems messy. Which one should it be? And if "type", how can I
// extend the "BankingAttributes" to "SpendingAccountAttributes" to tell the type system that
// those should be a part of the SpendingAccount's attributes?
export default {
Query: {
bankingAccounts: async(_source: string, _args: [], { dataSources}: Record<string, any>) : Promise<[BankingAccount]> => {
// The following makes a restful API to an `accounts` api route where we pass in the type as an `includes`, i.e. `api/v2/accounts?types[]=spending&types[]=savings
const accounts = await.dataSources.api.getAccounts(['spending', 'savings'])
const response = accounts.data.map((acc: BankingAccount) => {
const { fundsAvailable, accountFeatures, ...other } = acc.attributes
return {
id: acc.id,
type: acc.type,
balanceAvailableForWithdrawal: fundsAvailable,
// accountFeatures fails the compilation with the following error:
// "accountFeatures does not exist on type 'SpendingAccountAttributes | SavingsAccountAttributes'
// What's the best way to handle this so that I can pull the accountFeatures
// for the spending account (which is the only type of account this attribute will be present for)?
accountFeatures,
...other
}
})
return response
}
}
}
【问题讨论】:
-
请将您的帖子分成多个帖子,每个帖子一个问题。
-
@DanielRearden 我已经删除了所有与类型或接口无关的问题。我将留下其余的,因为它们密切相关
标签: typescript typescript2.0 typescript-types