the Vue ref attribute is struggling to accurately determine the data type

Are you looking to include an additional property in a composeable method, but encountering an error stating

property 'isActive' does not exist on type '{ id: string; text: string; }'

Below is the code snippet:

import { ref, type Ref } from 'vue';

type ActiveItemType = {
  text: string;
  isActive?: boolean;
};

export const useActiveItems = <T extends ActiveItemType>(data: T[]) => {
  let active = '';

  function activeMapper(d: T) {
    return {
      ...d,
      isActive: d.text === active,
    };
  }
  const itemsData = data.map(activeMapper);

  const items = ref(itemsData) as Ref<T[]>;

  function onSetActive(text: string) {
    active = text;
    items.value = items.value.map(activeMapper);
  }

  // initially set the first item
  if (items.value[0]) {
    items.value[0].isActive = true;
  }

  return {
    items,
    onSetActive,
  };
};

const { items } = useActiveItems([
  {
    id: '1',
    text: 't1'
  },
  {
    id: '2',
    text: 't2'
  },
]);

if (items.value[0]) {
  items.value[0].isActive; // ERROR
}

Access the TypeScript playground link

Through trial and error, it seems that defining a new type within the method resolves the issue. However, uncertain if this is the correct approach? Or should types only be specified in method headers i.e., within <>?

type U = T & ActiveItemType;
const items = ref(itemsData) as Ref<U[]>;

Answer №1

After reading this comment on an issue:

The use of generics with ref or reactive requires casting to as Ref<T> and as reactive<T> when you are confident that the type does not contain any nested refs, as ref and reactive automatically unwrap nested refs

   import {ref, Ref} from 'vue';
  // ... 
   const data = ref(dataItems) as Ref<T[]>;

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

vuex: The decision between using $store.commit and directly calling the function

Recently, I discovered an interesting technique where store mutation functions can be passed into HTML events. Here's an example: //In the template <input name="the_field" :value="the_field" @input="updateField"/> // In the component methods ...

Attempting to map an object, however it is showing an error stating that the property 'title' does not exist on type 'never'

While attempting to retrieve data from the Bloomberg API, I encountered an issue when trying to extract the title from the response object. The error message received was: Property 'title' does not exist on type 'never'. Below is the co ...

What steps do I need to take to integrate the Firebase Admin SDK into my Angular project?

Is there a way to integrate Firebase Admin SDK into my Angular application? Currently, I am using Firebase Authentication services in my application and everything I need for user registration and authentication is handled by Angularfire2. I've read ...

What is the best way to retrieve the chosen item within a Tabmenu component in Primeng?

I have created a simple array of MenuItem objects to populate the Tabmenu component from Primeng. Here is an example: .ts file: items = MenuItem[]; activeItem = MenuItem; //constructor, etc... ngOnInit() { this.items = [ {label: &a ...

Challenges with Typescript Integration in Visual Studio 2013

Currently diving into typescript as a newbie while going through the Angular tutorial using Visual Studio 2013 for work, which is also new to me. The frustrating part is that Visual Studio seems to be assuming I am going to use a different language (judgin ...

Replacing a push operation in JavaScript with a splice operation

Upon entering a screen, 5 promises are automatically loaded using promise.all. The issue is that they are executed in a random order, and within each function, I use a push to store the information. The problem arises when I need to change the push to a s ...

The interface 'IProduct' does not include several properties found in type 'IProduct[]', such as length, pop, push, concat, and many more

My goal is to transfer data between parent and child components using React and TypeScript. I have defined the following interfaces: export interface IProduct { id: string; name: string; price: string; image: string; ...

Crafting a versatile type guard in TypeScript - step by step guide!

Issue with Generic Type Guard I'm facing a problem while trying to create a generic type guard for various Token types. The current implementation I have is as follows: export function isToken<T extends Token>(token: any): token is T { for (c ...

Are you interested in creating dynamic tables/models with Sequelize?

Currently, I am exploring a theoretical question before diving into the implementation phase. The scenario is as follows: In my application, users have the ability to upload structured data such as Excel, CSV files, and more. Based on specific requirement ...

Error: Import statement is invalid outside of a module in next.js

Every time I attempt to run the register.tsx page in my next.js project, I encounter the error message shown below. My Next.Js project utilizes TypeScript. import React, { useState } from 'react'; ^^^^^^ SyntaxError: Cannot use import st ...

Angular route fails to load the HTML file

In the process of developing a route within an Angular application, I have successfully implemented 3 routes. However, one particular route is giving me trouble. I have three folders that need to redirect HTML based on the option chosen. In Angular, I cre ...

The Angular Tailwind utilities are functioning smoothly during development, but encountering issues in production environments

I've noticed that when I compile my Angular project using Tailwind CSS, I sometimes receive the message "No utility classes were detected in your source files," and other times it builds without any warnings but the utilities are still missing. This i ...

Ways to change the visibility of a view depending on a state in vuex?

If I have a button <Button> Log me in! </Button>, and I want to dynamically change its style based on the state of my Vuex app (state.user is not null). How should I properly implement this functionality? I'm considering creating a field ...

Verifying Vuejs values post-click testing

<!-- custom template --> <div> <textarea v-model="someText">{{someText}}</textarea> <div v-if="hasError">Oops, an error occurred</div> <input v-on:click="store" type="submit" value="update" /> </div ...

Outdated Node_modules directory leading to compilation issues

After encountering issues updating Vue to the latest version, I decided to rename my node_modules folder to node_modules_OLD and perform an npm install. This successfully updated everything, but now when attempting to run npm run build, I am facing the err ...

Exploring the power of Vue.js with dynamic HTML elements and utilizing Vue directives within Sweet Alert

new Vue({ el: '#app', data(){ results: [] } }); I need assistance with implementing Vue directives, events, etc. within the markup of a Sweet Alert. The goal is to display an alert using Sweet Alert that include ...

Handling exception type in child_process exec method - NodeJS with Typescript integration

Check out this sample code: const execPromise = util.promisify(exec); try { const { stdout } = await execPromise(cliCommand); } catch (error) { if (error instanceof S3ServiceException) { // error message is not handled correctly console ...

The rendering of the template in Vue is facing issues when using Webpack, with complaints about the runtime-only build

Initially, I want to mention that my goal is to seamlessly incorporate Vue into my current codebase. I have discovered that Webpack is a valuable tool and have configured it to suit my requirements. While I am not an expert on webpack, I grasp the basics a ...

Incorporating a template or component into the Vue.js router.js

If someone can provide me with an answer on how to import templates into route.js in Vue.js, I would greatly appreciate it:) Here is my HTML: <head> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="h ...

Discover the magic of v-model in Vue 3 Composition API

Can someone help with managing reactivity in form fields using Vue3 Composition API? I'm having trouble getting my code to work correctly. When I type text into the input field, Vue devtools does not show any changes in the ref data. Here's a sim ...