【问题标题】:Apollo Client return type in TypescriptTypescript 中的 Apollo 客户端返回类型
【发布时间】:2021-01-13 13:53:51
【问题描述】:

我正在尝试在返回 Apollo 客户端的类中构建一个简单的函数。这是我的代码:

import appConfig from 'config/app-config';
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import LocalStorageKeys from 'constants/local-storage-keys';
import { setContext } from '@apollo/client/link/context';

export class ApolloClientServiceImpl {
  private cache: InMemoryCache;
  constructor() {
    this.cache = new InMemoryCache();
  }

  createApolloClient(idToken: string): unknown {
    const httpLink = createHttpLink({
      uri: appConfig.hasura.url,
    });
    const authLink = setContext((_, { headers }) => {
      let bearerToken = localStorage.getItem(LocalStorageKeys.TOKEN);
      if (idToken) {
        bearerToken = idToken;
      }
      return {
        headers: {
          ...headers,
          authorization: bearerToken ? `Bearer ${bearerToken}` : '',
        },
      };
    });
    return new ApolloClient({
      link: authLink.concat(httpLink),
      cache: this.cache,
    });
  }
}

我的问题在于createApolloClient 函数的返回类型。如果我将其设置为 ApolloClient<InMemoryCache> 并在 return 语句中执行以下操作:

return new ApolloClient<InMemoryCache>({
      link: authLink.concat(httpLink),
      cache: this.cache,
    });

然后我得到以下错误:

Type 'InMemoryCache' is not assignable to type 'ApolloCache<InMemoryCache>'.
  Types of property 'restore' are incompatible.
    Type '(data: NormalizedCacheObject) => InMemoryCache' is not assignable to type '(serializedState: InMemoryCache) => ApolloCache<InMemoryCache>'.
      Types of parameters 'data' and 'serializedState' are incompatible.
        Type 'InMemoryCache' is not assignable to type 'NormalizedCacheObject'.
          Index signature is missing in type 'InMemoryCache'.ts(2322)

Apollo 客户端文档上关于这个主题的文档很少,因此我的问题是,这个函数的正确返回类型是什么?

编辑:如果我只留下来:

    return new ApolloClient({
      link: authLink.concat(httpLink),
      cache: this.cache,
    });

并将返回类型更改为ApolloClient&lt;NormalizedCacheObject&gt;,这样就可以修复所有错误。感谢 Alluan Hadad。

【问题讨论】:

  • new ApolloClient&lt;InMemoryCache&gt; 不好。应该是new ApolloClient
  • @AluanHaddad 原来这解决了这个问题。非常感谢!
  • 没问题。指定显式类型参数,尤其是在传递值时,是一种反模式。正确的打字稿尽可能地利用类型推断

标签: typescript apollo react-apollo apollo-client


【解决方案1】:

查看我的课程。返回类型为ApolloClient&lt;NormalizedCacheObject&gt;

import { InMemoryCache, NormalizedCacheObject } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { FragmentMatcher } from "apollo-client/core/LocalState";
import { ApolloLink } from "apollo-link";
import { onError } from "apollo-link-error";
import { HttpLink } from "apollo-link-http";

enum EApolloCLientCredentials {
    DEFAULT_OMIT = "omit",
    INCLUDE = "include",
    SAME_ORIGIN = "same-origin",
}

class ClsApolloClient {
    private _httpLink: HttpLink;
    private _credentials: EApolloCLientCredentials;
    private _fragmentMatcher: FragmentMatcher | undefined;
    private _graphqlServerUrl: string;
    private _cacheInMemoryRules: Record<string, any>;
    private _apolloClient: ApolloClient<NormalizedCacheObject>;

    constructor(
        graphqlServerUrl: string,
        credentials: EApolloCLientCredentials = EApolloCLientCredentials.DEFAULT_OMIT,
        fragmentMatcher?: FragmentMatcher,
        cacheInMemoryRules: Record<string, any> = {}
    ) {
        this._graphqlServerUrl = graphqlServerUrl;
        this._credentials = credentials;
        this._fragmentMatcher = fragmentMatcher;
        this._cacheInMemoryRules = cacheInMemoryRules;

        this._apolloClient = this.initApolloClient();
    }

    get apolloClient(): ApolloClient<NormalizedCacheObject> {
        return this._apolloClient;
    }

    get httpLink(): HttpLink {
        return this._httpLink;
    }

    get cacheInMemoryRules(): Record<string, any> {
        return this._cacheInMemoryRules;
    }
    set cacheInMemoryRules(cacheInMemoryRules: Record<string, any>) {
        this._cacheInMemoryRules = cacheInMemoryRules;
        this._apolloClient = this.initApolloClient();
    }

    get credentials(): EApolloCLientCredentials {
        return this._credentials;
    }

    set credentials(credentials: EApolloCLientCredentials) {
        this._credentials = credentials;
        this._apolloClient = this.initApolloClient();
    }

    get fragmentMatcher(): FragmentMatcher | undefined {
        return this._fragmentMatcher;
    }

    set fragmentMatcher(fragmentMatcher: FragmentMatcher | undefined) {
        this._fragmentMatcher = fragmentMatcher;
        this._apolloClient = this.initApolloClient();
    }

    private initApolloClient(): ApolloClient<NormalizedCacheObject> {
        const errorLink = onError(({ graphQLErrors, networkError }) => {
            if (graphQLErrors)
                graphQLErrors.forEach(({ message, locations, path }) =>
                    console.log(
                        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
                    )
                );

            if (networkError) console.log(`[Network error]: ${networkError}`);
        });

        this._httpLink = new HttpLink({
            uri: this._graphqlServerUrl,
            credentials: this._credentials,
        });
        const links = [errorLink, this._httpLink];
        const apolloClient: ApolloClient<NormalizedCacheObject> = new ApolloClient(
            {
                link: ApolloLink.from(links),
                cache: new InMemoryCache({
                    ...this._cacheInMemoryRules,
                    addTypename: false,
                }),
                fragmentMatcher: this._fragmentMatcher,
            }
        );
        return apolloClient;
    }
}

export { EApolloCLientCredentials, ClsApolloClient };

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 2020-01-13
    • 2019-01-04
    • 2019-06-25
    • 2018-08-26
    • 2023-03-27
    • 2020-12-05
    • 2020-01-19
    • 2019-11-02
    相关资源
    最近更新 更多