Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use in a project that is setup using Vue CLI@3 and TypeScript? #444

Closed
praveenpuglia opened this issue Nov 16, 2018 · 12 comments
Closed

Comments

@praveenpuglia
Copy link

praveenpuglia commented Nov 16, 2018

td;dr
How do I include vue-apollo in a project that already uses TypeScript?

I created a fresh vue project using vue cli@3 and using typescript.

Then I added the vue-apollo plugin which modified my main.ts file to add

apolloProvider: createProvider(),

in the vue instance creation.

But the compiler complains about this.

Argument of type '{ router: VueRouter; store: Store<{}>; apolloProvider: { provide: () => {}; }; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>'.

Object literal may only specify known properties, and 'apolloProvider' does not exist in type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>'. [2345]

I can see that there is a types directory in the vue-apollo package I fetched from npm but not sure how to use them.

I also get the following

[ts] Could not find a declaration file for module '@/vue-apollo'. '/Users/praveen/code/voicezen/repos/voicezen-ui/src/vue-apollo.js' implicitly has an 'any' type. [7016]

for the following import in main.ts

import { createProvider } from '@/vue-apollo';

I get that this might be coming from the noImplicitAny rule but then changing the generated vue-apollo.js to vue-apollo.ts also doesn't solve the problems.

Changing it to .ts removes the compiler errors from main.ts about the above two but then I get the following.

Could not find a declaration file for module 'vue-cli-plugin-apollo/graphql-client'. '/Users/praveen/code/voicezen/repos/voicezen-ui/node_modules/vue-cli-plugin-apollo/graphql-client/index.js' implicitly has an 'any' type.

for

import {
  createApolloClient,
  restartWebsockets
} from 'vue-cli-plugin-apollo/graphql-client';

To fix this, I can add a module declaration in my typings like this but is that the right way?

declare module 'vue-cli-plugin-apollo/graphql-client';

and the onLogin or onLogout param apolloClient starts complaining about them being implicitly any type too.

@joe-re
Copy link
Contributor

joe-re commented Nov 17, 2018

@praveenpuglia
I guess we have to improve vue-cli-plugin-apollo to deal with it.

https://github.com/Akryum/vue-cli-plugin-apollo

For now, you can define like below codes on main.ts to fix error report.

// add module import and define apolloClient type
import { ApolloClient } from "apollo-client";
import { SubscriptionClient } from "subscriptions-transport-ws";
import { InMemoryCache } from "apollo-cache-inmemory";

type VueApolloClient = ApolloClient<InMemoryCache> & {
  wsClient: SubscriptionClient;
};

//... some codes ...

// set apolloClient type
export async function onLogin(apolloClient: VueApolloClient, token: string) {
  //...
}

// Manually call this when user log out
export async function onLogout(apolloClient: VueApolloClient) {
  //...
}

@praveenpuglia
Copy link
Author

Thanks for the comment. This really helps!

I have one more small doubt.

for onLogin and onLogout, if I have multiple clients, do I need to call resetStore on all the clients?

If so, how do I pass all clients to say, onLogout while calling from a component or store?

I tried this.$apollo.provider.clients and this.$apolloProvider.clients both of which result in type errors even though the clients exist there.

@quentinus95
Copy link
Contributor

Currently this is what I'm doing:

const clients = this.$apollo.provider.clients
for (const client of Object.keys(clients)) {
  await clients[client].resetStore()
}

@praveenpuglia
Copy link
Author

@quentinus95 this works, but TS complains about this.$apollo.provider doesn't have clients.

@joe-re
Copy link
Contributor

joe-re commented Nov 20, 2018

@praveenpuglia
I have made PR to deal with that.
#447

For now, please ignore error report on typescript.

@Akryum
I'm sorry to bother you though, I would be grateful if you would check that PR. 🙇

@praveenpuglia
Copy link
Author

Thanks so much! Really waiting for this to get merged.

@jeissler
Copy link

Hi,

I'm facing a similar issue to this. I install a new project using the cli + typescript and have done these same workarounds, but even after that I'm getting the below errors (multiples) and can't seem to find anything regarding this. Any info you can provide is appreciated; I'm new to Typescript, but need to use it for this project. Thanks in advance!

ERROR in /Users/jeissler/Projects/www/vue-test-3/node_modules/apollo-client/data/store.d.ts
34:17 Cannot use namespace 'ExecutionResult' as a type.
    32 |     markMutationResult(mutation: {
    33 |         mutationId: string;
  > 34 |         result: ExecutionResult;
       |                 ^
    35 |         document: DocumentNode;
    36 |         variables: any;
    37 |         updateQueries: {

@joe-re
Copy link
Contributor

joe-re commented Jan 8, 2019

@jeissler
it's not reproduced on my env.
could you show us full of example to repro?

@jeissler
Copy link

jeissler commented Jan 8, 2019

@joe-re thanks for your reply; I've abandoned typescript for this project 20 days ago citing the above issues. It seems like TS isn't something that's well supported although I am still hoping to use the vue-apollo package.

@Akryum Akryum closed this as completed Jan 9, 2019
@praveenpuglia
Copy link
Author

Version - 3.0.0-beta.27

Hi! Thanks so much for merging the PR but I feel it still doesn't solve the problem entirely.

I do get this.$apollo.provider.clients working in Component code but each Client here is of type ApolloClient.

The onLogin or onLogout methods accept Client but it's not same as ApolloClient because it also expect wsClient int the passed in apolloClient which violates ApolloClient type signature.

How can I resolve that?

@praveenpuglia
Copy link
Author

Ok, So I solve it this way. Just let me know if this is correct.

In vue-apollo.ts, I created these two.

export type VueApolloClient = ApolloClient<InMemoryCache> & {
  wsClient: SubscriptionClient;
};

export interface VueApolloClients {
  [key: string]: VueApolloClient;
}

And then in the component where I call the onLogout method, I did the following.

onLogout(this.$apollo.provider.clients as VueApolloClients);

Finally going back to vue-apollo.ts I changed the signatures of onLogin and onLogout to accept
multiple clients, loop through them and then call resetStore and restartWebsockets methods.

export async function onLogin(clients: VueApolloClients, token: string) {
  if (typeof localStorage !== 'undefined' && token) {
    localStorage.setItem(AUTH_TOKEN, token);
  }
  resetCacheAndSockets(clients);
}

async function resetCacheAndSockets(clients: VueApolloClients) {
  for (const client of Object.keys(clients)) {
    if (clients[client].wsClient) {
      restartWebsockets(clients[client].wsClient);
    }
    try {
      await clients[client].resetStore();
    } catch (e) {
      /* tslint:disable-next-line:no-console */
      console.log(
        '%cError on cache reset (logout)',
        'color: orange;',
        e.message
      );
    }
  }
}

@thearabbit
Copy link

I tried to change tsconfig

{
  "compilerOptions": {
     ..............
    "allowJs": true
  },

Please advise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants