Ways to access Vue computed attributes in typescript

When attempting to utilize a computed property within another one or inside a method, I encountered the following error message:

Property 'comments' does not exist on type 'Vue'

import { Component, Vue } from 'vue-property-decorator'
@Component({
  computed: {
    comments(): Comment[] {
      return this.$store.getters['comments/getComments'];
    },
    hasComments(): boolean {
      return (0 !== (this as any).comments.length); // Property 'comments' does not exist on type 'Vue'
    }
  }
})
export default class Test extends Vue {
  public get commentsCount(): number {
    return (this as any).comments.length; // Property 'comments' does not exist on type 'Vue'
  }
}

In order to avoid errors, I substituted (this as any).comments, but it raises the question of why we would use typescript and disregard type checking by using any.

Answer №1

One issue is that the variable comments exists in the Javascript runtime but is not defined in Typescript. To resolve this, declare the variable and use the ! operator after its definition to assert it as non-null. This operation informs Typescript that the variable will be initialized elsewhere (in this case, by a decorator).

Snippet:

public comments!: TYPE_OF_COMMENTS;

Full code:


import { Component, Vue } from 'vue-property-decorator'
@Component({
  computed: {
    comments(): Comment[] {
      return this.$store.getters['comments/getComments'];
    },
    hasComments(this: Test): boolean {
      return (0 !== this.comments.length);
    }
  }
})
export default class Test extends Vue {
  public comments!: TYPE_OF_COMMENTS;

  public get commentsCount(): number {
    return this.comments.length; // Property 'comments' does not exist on type 'Vue'
  }
}

Update:

To resolve the issue with hasComments, adjust the value provided for the this instance to reference the actual component instead of the default Vue instance. You can do this as follows:

hasComments(this: Test): boolean {
      return (0 !== this.comments.length);
    }

This way, the this instance will have the correct type definitions for the component (Test).

Answer №2

In my experience with Vue 2, I have encountered similar errors in the past (Vue 3 is significantly improved, especially with the composition API). While there wasn't a single specific solution, one common fix that I found was ensuring that my computed properties had an accurate return type and that a default value was used for them.

I wanted to suggest adding this as a comment, but unfortunately I don't have enough reputation. Have you considered providing a default value in your comments() return? Although you've specified it to return a Comment[], TypeScript/Vue might not recognize that the store value you're fetching matches that type (or if it even exists yet).

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 Angular 2: Incorporating multiple HTML pages into a single component

I am currently learning Angular 2 and have a component called Register. Within this single component, I have five different HTML pages. Is it possible to have multiple templates per component in order to navigate between these pages? How can I implement ro ...

I am currently utilizing Laravel 9.* along with Vue and InertiaJS to edit and modify the information of a pre-existing user

There seems to be an error based on the log: local.ERROR: Call to undefined method App\Models\User::user() {"userId":14,"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method App\\Model ...

Issue: The formGroup function requires a valid FormGroup instance to be passed in. Data retrieval unsuccessful

My goal is to retrieve user data from a user method service in order to enable users to update their personal information, but I'm encountering an error. Currently, I can only access the "prenom" field, even though all the data is available as seen in ...

How to reference 'this' within a d3 callback when using Angular 7

In an Angular directive, I am trying to access a class-level variable inside a callback function. To achieve this, I used an arrow function but the 'this' keyword is still not pointing to the directive. this.itemRects.selectAll('rect') ...

A guide to utilizing ngFor in Angular 7 to loop through nested JSON and display it in a ul li

Looking to insert a nested JSON into an unordered list using ngFor loop in Angular. Here's the expected output format in HTML: home.component.html <div class="col-md-3" id="leftNavBar"> <ul *ngFor="let item of nestedjson"> <li c ...

Populating a class object with all fields simultaneously from a FormGroup

Working with Angularjs projects involves creating an input form with various fields to collect data. The provided documentation includes examples on how to retrieve individual field values as well as how to save all the fields at once, potentially in a cla ...

Clear out the information from the previous table and set up a fresh one using DataTables

I am facing difficulties with datatables. I am using it to showcase data retrieved from a vuejs request, but I am unable to receive the sorted data after making a second request. The initial request fetches the data successfully as shown below: var dates ...

limiting the number of HTTP requests within a JavaScript forEach loop

In my current coding situation, I am facing an issue where the HTTP requests are being made simultaneously within a forEach loop. This leads to all the requests firing off at once. const main = async () => { items.forEach(async (i: Item) => ...

An improved approach for implementing ngClass condition in Angular components

Searching for a more concise way to rewrite the following condition: [ngClass]="{ 'class1': image.isAvailable && (image.property !== true && !null), 'class2': image.isAvailable && ...

What is the best way to fetch the chosen item in an Angular select dropdown

I am working on a dropdown that populates with items of type ObjectA. item.component.html: <label>items list: <select formControlName="itemsCtl" (change)="onChange()"> <option *ngFor="let item of itemList" [value]="item">{{i ...

Is there a way to transform a complex nested class object into a simple object without losing its methods

Is there a way to convert a deeply nested class object into a plain Object type while still retaining methods like getters and setters? class A { id = ""; data = { sync: {} }; } class SyncService { syncResultServiceA = { ...

Defining Multiple Types in Typescript

I have created an interface in a TypeScript definition file named d.ts: declare module myModule { interface IQedModel { field: string | string[]; operator: string; } } In an Angular controller, I have utilized this interface like ...

Using NestJS to pass request and response parameters

I have a function in my services set up like this: ` @Injectable() export class AppService { getVerifyToken(req: Request, res: Response) { try { let accessToken = process.env.ACCES_TOKEN_FB; let token = req.query["hub.verify_t ...

Creating layers of object declarations

Looking for assistance on the code snippet below. type Item = { id: number; size: number; } type Example = { name: string; items: [ Item ]; } var obj: Example = { name: "test", items: [ { i ...

The vuex module could not be located

I am just starting out with Vue and I am using Vue CLI. Below is the code I have written: App.vue: <template> <div id="App"> <Count/> </div> </template> <script> import Count from './components/Count&apo ...

Enhancing Twilio LocalVideoTrack with custom start and stop event handling

Is it possible to customize the events triggered when a video starts or stops playing? I attempted the code below, but unfortunately, it did not yield any results: this.videoTrack = screenTrack as LocalVideoTrack; this.videoTrack.stopped = function (eve ...

Mastering Checkbox State Control in Vue3 Using Component Props

This scenario is as follows: Parent component: It holds a dynamic Todo object with a checked state {checked: true} and sends it to the Todo component. Todo component: Takes in the Todo as a prop and links the checked value to a checkbox. When the checkbo ...

Tips for retrieving next-auth authOptions from an asynchronous function

I need to retrieve values from AWS Secrets Manager and integrate them into the authOptions configuration for next-auth. The code implementation I have is as follows: export const buildAuthOptions = async () => { const secrets: AuthSecrets = await getS ...

Implementing custom query filtering in apollo-server-express

Most of the requests and changes processed by my server require authorization. But, there are a few specific resolvers that need to be public such as sign-in, register, and forgot-password. How can I enable these resolvers to be accessed selectively and au ...

Include a new course based on a specific situation

Is it possible to conditionally add a specific class using vue js? In my DataStore, I have two values defined in TypeScript: value1: 0 as number, value2: 0 as number Based on the values of value1 and value2, I want to apply the following classes in my te ...