Home > front end >  Typescript says property doesn't exist though it does?
Typescript says property doesn't exist though it does?

Time:10-21

I have the following code.

const ACCOUNTS_QUERY = gql`
  {
    accounts {
      id
      name
      number
    }
  }
`;

interface Accounts {
  accounts: [
    {
      id: number;
      name: string;
      number: string;
    }
  ];
}

export default defineComponent({
  name: "AccountsView",
  setup() {
    const { result, loading, error } = useQuery<Accounts>(ACCOUNTS_QUERY);

    return {
      accounts: result.accounts,
    }

Here I get TS2339: Property 'accounts' does not exist on type 'Ref<Accounts | undefined>' in the return.

Now if I swap the return statement for:

    return {
      result,
    }

I can access result.accounts in the template and iterate over it with v-for. Why can't I return result.accounts?

CodePudding user response:

The type that is returned is Ref<Accounts | undefined>, but you are using the result as an Accounts type. I don't know what vue does when you return a Ref (might be that it resolves it in some way, but I never worked with vue).

I think that what you are trying to do is an asynchronous call, so at the moment you want to access the props of result, result is not resolved yet (asynchronous backend call via graphQL).

You could add a break point and see whats inside of result at that very moment (or use console.log() for that)

CodePudding user response:

I see two issues:

  1. According to the documentation, useQuery returns the data as data, not as results.

  2. Since loading the data is asynchronous, data may be undefined, for instance, if loading or error is true (the type of useQuery's return value's data property is Accounts | undefined). You have to narrow that type for TypeScript to know it's valid to look for an accounts property on it.

So:

const { data, loading, error } = useQuery<Accounts>(ACCOUNTS_QUERY);
if (data) {
    data.accounts
    //    ^? (property) Accounts.accounts: [{ id: number; name: string; number: string; }]
}

Playground link

  • Related