Why is Typescript claiming a property doesn't exist when it clearly does?

Below is the code I am working with:

import { useQuery } from "@vue/apollo-composable";

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

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

If I change the return statement to:

    return {
      result,
    }

By doing this, I can access result.accounts in the template and iterate over it using v-for. But why am I unable to directly return result.accounts?

Answer №1

The returned type is Ref<Accounts | undefined>, yet you are treating it as an Accounts type. It's unclear how Vue handles the returning of a Ref (it may resolve it in some way, but my experience with Vue is limited).

It seems like you are attempting an asynchronous call, so when you try to access the properties of the result, it is likely not yet resolved (due to an asynchronous backend call using graphQL).

To better understand what is inside result at that moment, consider setting a break point or using console.log() for debugging.

Answer №2

I've noticed a couple of issues:

  1. As per the documentation, the result property in the return value of @vue/apollo-composable's useQuery is a Ref. You should access the value property to get to accounts (should be result.value.accounts, not just result.accounts).

  2. Since data loading is asynchronous, result.value might be undefined; the type of result is Ref<Accounts | undefined>, not Ref<Accounts>. It's essential to narrow that type for TypeScript to recognize it as valid to search for an accounts property.

Therefore:

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

Playground link

Answer №3

In the end, I opted for a different solution.

  data() {
    const users: User[] = [];

    return {
      users,
    };
  },
  beforeMount() {
    useQuery<Users>(USERS_QUERY).onResult(
      (handler) => (this.users = handler.data.users)
    );
  },

I appreciate your guidance in helping me find the right path.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the option of integrating Vuetify snackbar as a universal custom component in Vue.js

I recently implemented a Snackbar to display success messages in Vue.js and now I want to create a global custom Snackbar component. <template> <div name="snackbars"> <v-snackbar v-model="snackbar" :colo ...

Exploring the canDeactivateFn syntax with Angular Documentation

As a first-year university student, I recently discovered that the canDeactivate() guard in Angular is deprecated, while the canDeactivateFn guard functions without any issues. Admittedly, navigating through official documentation is still new to me. From ...

A guide on integrating a vue-concurrency Task Creator with argument support

I've been grappling with my Vue 3 / TypeScript app and the vue-concurrency library. Everything is nearly in place, but configuring a Task Creator to accept arguments has proven to be quite challenging. Following the Task Creators pattern outlined in ...

Passing parameters by reference in TypeScript

It is possible to pass parameters by reference in C#. For example: private void Add(ref Node node) { if (node == null) { node = new Node(); } } Add(ref this.Root); After executing Add(ref this.Root), th ...

Having issues constructing a Gridsome project: a modal triggers an error stating that 'window is not defined'

During development, my project functions properly, but encounters errors in build mode. The specific error message is: ReferenceError: window is not defined at Object.<anonymous> (node_modules/vue-js-modal/dist/index.js:1:210) at __webpack_require__ ...

Dynamically importing TypeScript interfaces for React code splitting

Is it possible to utilize dynamic import('path') for an exported interface? ...

The TypeScript compiler does not transpile the .at() function

While converting TypeScript to JavaScript compatible with NodeJS v14 using the provided configuration: { "compilerOptions": { "lib": ["es2020"], "rootDir": "src", "outDir": "bui ...

"Exploring the capabilities of VueX through Mixin implementation

Before diving into coding, I wanted to make sure I have a solid conceptual understanding of what I'm working on. I have multiple components that import a mixin. This mixin includes a web API call to fetch links from a (HATEOAS) API, allowing the UI t ...

Exploring ways to customize or replace the extended CurrencyPipe type in Angular

I'm currently working on reusing an existing currency pipe from Angular common. My objective is to truncate the .00 when the value is round. Here's the code I've come up with: /** Transform currency string and round it. */ @Pipe({name: &apo ...

Are there any methods to incorporate Facebook and Google login into an Ionic progressive web app (PWA)?

After successfully developing an app in Ionic 3 for Android and iOS, I encountered a problem when adding the browser platform. The Facebook and Google login features were not functioning as expected. Despite the assurance from Ionic documentation that the ...

Guidance on establishing an Array data type for a field in GraphQL Type declarations

Hey there! Currently, I'm working on my Nodejs project and facing a little dilemma. Specifically, I am trying to specify the type for graphQL in the code snippet below. However, I seem to be struggling with defining a field that should have a Javascri ...

The HttpClient.get('/') request with {observe: 'response'} is failing to retrieve some headers

Currently, I'm in the process of writing an API GET request by utilizing HttpClient.get(). Upon passing in the option to observe the response, I've encountered an issue where accessing the .keys() does not provide me with any headers apart from C ...

Errors in type checking observed in app.reducer.ts file for Angular NgRx

I encountered an issue with my login/logout state management setup. The error message I received is as follows: When trying to assign '(state: State | undefined, action: authActions) => State' to type 'ActionReducer<State, Action>& ...

Manifest for npm module

After releasing my first npm package, I realized that I needed to implement a declaration file ("*.d.ts") when integrating it into one of my projects. Despite multiple attempts, I have not been able to successfully integrate it and have spent days trying t ...

After extraction from local storage, the type assertion is failing to work properly

I have a unique situation in my Angular project where I have stored an array of data points in the local storage. To handle this data, I have created a custom class as follows: export class Datapoint { id: number; name: string; // ... additional pr ...

Having trouble getting Vue JS 2.0 to display content?

When working with Vue (^2.0.0-rc.6) and Browserify, the entry point is index.js: import Vue from 'vue' import App from './containers/App.vue' new Vue({ // eslint-disable-line no-new el: '#root', render: (h) => h(App) ...

Step-by-step guide on integrating async and await functionality into Vuetify rules using an ajax call

I'm currently using Vuetify form validation to validate an input field, and I'm exploring the possibility of making an ajax get call await so that I can utilize the result in a rule. However, my attempts at this approach have not been successful! ...

Customizable column layout in react-grid-layout

I am looking to implement a drag and drop feature in which users can place items into a grid without fixed columns. The goal is that if an item is dragged from outside the grid boundaries and dropped to the right (an empty area), the grid will automaticall ...

Cypress encountered an error: Module '../../webpack.config.js' could not be located

Every time I attempt to run cypress, an error pops up once the window launches stating "Error: Cannot find module '../../webpack.config.js'" Within my plugins>index.js file, I have the following in module.exports webpackOptions: require(&apos ...

Achieve accurate mouseover interaction in a ThreeJS VueJS application by dynamically altering the viewport

I managed to accomplish an amazing feat: I designed a menu consisting of 4 unique shapes. As you hover over each shape, it undergoes a color change, grows in size, and shifts the other shapes while slowing down its rotation. To achieve this, I delved into ...