如何正确输入 Apollo Client defaultOptions?

How do I correctly type the Apollo Client defaultOptions?

我正在这样设置 Apollo 客户端。

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'all',
  },
  mutate: {
    errorPolicy: 'all',
  },
};
return new ApolloClient({
  link: ApolloLink.from([authLink, errorLink, webSocketOrHttpLink]),
  defaultOptions, // Typescript don't like this.
  queryDeduplication: true,
});

打字稿给出了这个错误:

Type '{ watchQuery: { fetchPolicy: string; errorPolicy: string; }; query: { fetchPolicy: string; errorPolicy: string; }; mutate: { errorPolicy: string; }; }' is not assignable to type 'DefaultOptions'.ts(2322)
ApolloClient.d.ts(23, 5): The expected type comes from property 'defaultOptions' which is declared here on type 'ApolloClientOptions<NormalizedCacheObject>'

根据文档,this 应该如何完成。

如何使用正确的类型构造 defaultOptions

如果你检查库的代码,似乎这里有问题

//defination of default options
export interface DefaultOptions {
 watchQuery?: Partial<WatchQueryOptions>;
 query?: Partial<QueryOptions>;
 mutate?: Partial<MutationOptions>;  
}

//defination of QueryOptions
export interface QueryOptions<TVariables = OperationVariables>
  extends QueryBaseOptions<TVariables> {
  /**
   * Specifies the {@link FetchPolicy} to be used for this query
   */
  fetchPolicy?: FetchPolicy;
}

//valid value for FetchPolicy type 
export type FetchPolicy =
  | 'cache-first'
  | 'network-only'
  | 'cache-only'
  | 'no-cache'
  | 'standby';

export type WatchQueryFetchPolicy = FetchPolicy | 'cache-and-network';

所以对于查询选项,您应该为 FetchPolicy 传递任何有效值,而 'cache-and-network' 是无效值。

在此处查看文档: https://github.com/apollographql/apollo-client/blob/main/src/core/watchQueryOptions.ts

2021 年:

如果您尝试使用 cache-and-network 作为 query.fetchPolicy 的默认设置:

为什么 cache-and-network 不允许 故意 query 的原因早在 2019 年就在这里解释过: https://github.com/apollographql/apollo-client/issues/3130#issuecomment-478409066
基本上,query()的behaviour/logic不支持这个策略。因此,他们在打字级别阻止了它。


React useQuery() 钩子

如果您使用的是 React,useQuery() 挂钩会遵循 watchQuery 而不是 query 的行为。所以配置 watchQuery 就足够了:

import {
  ApolloClient,
  InMemoryCache,
  HttpLink,
  DefaultOptions
} from "@apollo/client";

const defaultOptions: DefaultOptions = {
  watchQuery: {
    fetchPolicy: "cache-and-network",
    errorPolicy: "ignore",
    notifyOnNetworkStatusChange: true
  }
};
export const platformClient = new ApolloClient({
  link: new HttpLink({
    uri: "https://xxxxx",
    credentials: "same-origin"
  }),
  cache: new InMemoryCache(),
  defaultOptions
});