With Vue, the ref property does not automatically preserve the data types of nested private properties

Encountering this issue with both arrays and objects has been a challenge. While using shallowRef instead of ref might provide a temporary solution, the need for deep reactivity persists. I have resorted to casting as a workaround, but it is not ideal. What would be the most effective way to tackle this dilemma?

class Bar {
    private val = 1;
}

class Foo {
    private bar = new Bar();
}

const fooRef = ref(new Foo());

const foo: Foo = fooRef.value; // Property bar is missing in type {} but required in type Foo
const bar = fooRef.value.bar; // Property bar does not exist on type {}

const baz = ref([new Foo()]); 
const z = baz.value[0].bar.val; // Property bar does not exist on type {}

Key packages being used:

"typescript": "^5.6.3",
"vue": "^3.5.12",

Answer №1

ref generates a deeply reactive object that enables ref unwrapping. The ref type functions by extracting public members, allowing for unwrapping implementation. This is crucial for class types as their private members must align for compatibility.

Therefore, it's common for the type of fooRef.value to not be Foo, especially when reactivity APIs are used in the class implementation. In such cases, developers need to utilize type assertion if they are certain about the correct type.

This assertion can be made at the point where a value is utilized:

const foo = fooRef.value as Foo;

Alternatively, it can be done when creating a ref:

const fooRef = ref(new Foo()) as Ref<Foo>;

It's important to note that this approach differs from ref<Foo>(new Foo()), with the latter behaving similarly to ref(new Foo()).

Answer №2

To enhance security, it is advisable to remove private and possibly protected properties, thus limiting access only to the public interface:

Innovative Platform

type Accessible<T extends object> = {[K in keyof T]: T[K]} extends infer A ? A : never;
let data: Accessible<DataModel>;

data = dataRef.value;

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

The return type of a getter is `any` if the object contains a method and is processed by a generic function

I am facing an issue with my code where the getter's return type is set to any, even though the actual return type should be clear. There are certain additional functions triggering this behavior: // This is necessary for reproduction const wrapperFun ...

How can we enable WebStorm to provide auto-suggestions for custom-defined functions?

https://i.sstatic.net/GsPWz.png https://i.sstatic.net/GsPWz.png The first image demonstrates the ability to jump directly to the desired file. The second image illustrates the process of implementing this operation. ...

Vue input not reacting to v-model in Vuex state

I am attempting to simplify the explanation as much as possible. The structure I have includes a basic Vue root, Vuex store, and an input with v-model inside the navbar id. However, it seems that the input is not reactive... Why is that? https://i.sstati ...

When using NodeJS and TypeScript, the URL query function may encounter issues when multiple parameters are included

This is the code snippet for a controller in my route: export const getHotels = async ( req: Request, res: Response, next: NextFunction ) => { try { const hotels = await Hotel.find(req.query).limit(+req.query.limit); res.status(200).json ...

Applying the spread operator in the map function for copying objects

In my Angular application, I am attempting to copy an object and add a new property using the spread operator. To add the new property, I have created a method called 'addNewProperty(name)' which returns the property and its value. However, when ...

Currently, I am leveraging Vuetify to display an array of objects within an array of objects in a dropdown button

Suppose there is a json object structured like this: listofSubdomains:[{ "name": "domain1", "subdomain": [ { "name": "subdomain1" }, { "name": "subdomain2" ...

Changing the <style> dynamically within a Single File Component

Can the content within a scoped in a Single File Component be dynamically updated? ...

Maintaining the order of keys in JSON using TypeScript and custom type/class/interface

Currently, I am retrieving a JSON object from a database and mapping it to another JSON object. However, due to limitations in the column names of my database, I am required to manually assign some values. Below is a snippet of the model: ... InvoiceLineBa ...

Implement Vue.js transitions on elements to smoothly reveal additional content

Rather than a problem, this is more of a "how to" scenario. Imagine having a template structured like this (id tags are used for clarity) : <template> <div id="1" v-if="someCondition"></div> <div id="2" ...

Toggle the visibility of the navigation bar in Angular based on the user

I have implemented rxjs BehaviorSubject in my login page to transmit data to auth.service.ts, enabling my app.component to access the data stored in auth.service.ts. However, I now require the app.component to detect any changes made to the data in auth.se ...

Guide on verifying the presence of a value in a textbox using vue

I'm currently working on a form that requires only numbers and text input. Any characters like ., ,, or spaces are not allowed in the textbox. Here are some of the attempts I've made, but unfortunately, they did not yield the desired results: i ...

Display the latest distinct records in Vue.js

I've hit a roadblock in my project. @StephenThomas kindly assisted me with this issue: Vue.js only show objects with a unique property but I still need to make some adjustments. My current task involves creating a leaderboard for a game using Firest ...

The type 'JSX.Element' cannot be assigned to type 'Element'

After updating my dependencies, I encountered more build errors than before. While attempting to resolve them, one error remains persistent. The code snippet causing issues: children: Element[]; Element: JSX.Element; I attempted to address the problem ...

The module 'angular/common' was not found in the Angular 2 TypeScript

While experimenting with a sample login form in Angular 2, I encountered an issue when trying to import 'Form_Directives' as: import { FORM_DIRECTIVES } from '@angular/common'; An error was displayed stating that the angular/common m ...

The Vue component is only functioning partially and is not visible in the Vue inspector

I have a straightforward Vue component that is causing me some trouble. <template> <div class="field has-addons"> <div class="control is-expanded"> <div class="select is-fullwidth"> <select v-mode ...

Exploring Angular2's interaction with HTML5 local storage

Currently, I am following a tutorial on authentication in Angular2 which can be found at the following link: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492 I have encountered an issue with the code snippet below: import localSt ...

How can I incorporate a new function into a TypeScript class that already exists?

In my current angular 2 cli project, I am faced with the task of defining a plugin that does not have its own type definition. This plugin relies on a main library that already has its own typed definitions and is functioning properly. I have two files; t ...

Inert child component in Vue

Within an application utilizing a Vuex store, there exists a getter named getQueryParams. This getter retrieves an object that contains the parameters being sent to a database query. If any parameters are present (indicating that the user has performed a q ...

Utilizing Custom Validators in Angular to Enhance Accessibility

I'm struggling to access my service to perform validator checks, but all I'm getting is a console filled with errors. I believe it's just a syntax issue that's tripping me up. Validator: import { DataService } from './services/da ...

Exploring the integration of Vue data binding with Highcharts

I am facing an issue with a dynamic chart in a Vue framework. The chart's axis contents and data are supposed to change over time. Initially, I attempted to use setData() and setCategories() to update the chart with dynamic data. However, this approa ...