Typescript'te Apollo Client dönüş türü


Bir sınıf içinde Apollo Client döndüren basit bir fonksiyon oluşturmaya çalışıyorum. İşte kodum:

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,
    });
  }
}

Sorunum createApolloClient fonksiyonunun dönüş türünde yatıyor. Eğer bunu ApolloClient<InMemoryCache> olarak ayarlarsam ve dönüş ifadesinde şöyle bir şey yaparsam:

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

Sonra aşağıdaki hatayı alıyorum:

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 istemci belgelerinde bu konu hakkında çok az dokümantasyon var, bu yüzden sorum şu: Bu fonksiyonun doğru dönüş tipi nedir?

DÜZENLEME: Eğer sadece şunlarla kalırsam:

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

Ve dönüş türünü ApolloClient<NormalizedCacheObject> olarak değiştirin, bu hata ile ilgili her şeyi düzeltir. Teşekkürler Alluan Hadad.

Cevap #1

sınıfıma göz at. Dönüş türü ApolloClient<NormalizedCacheObject>

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 };

İlgili makaleler