Unpacking and reassigning variables in Vue.js 3 using TypeScript

I am working with a component that has input parameters, and I am experimenting with using destructuring assignment on the properties object to reassign variables with different names:

<script setup lang="ts">
const { modelValue: isSelected, date1: inputDate1 } = defineProps({
  modelValue: Boolean,
  date1: String
})

console.log(isSelected)

const date1 = 'abc'
console.log(date1)
</script>

<template>
  <div v-if="isSelected">Selected!</div>
</template>

In this piece of code, the variable modelValue is being reassigned to isSelected, and date1 is being reassigned to inputDate1.

However, there are two issues that arise from this code.

While editing at line const date1 = 'abc', an error occurs:

Duplicate key 'date1'. This may lead to name collision in the script or template tag. eslintvue/no-dupe-keys

This error seems to be inaccurate. If we modify the code as follows:

const date2 = 'abc'
console.log(date1)

We encounter another error when trying to log date1:

Cannot find name 'date1'. Did you mean 'date2'? ts(2552)

It appears that there is no other variable with the same name as date1. So why does the compiler flag it as a duplicate?

Additionally, during runtime, an exception or warning is thrown from the template:

[Vue warn]: Property "isSelected" was accessed during render but is not defined on instance.

However, the line:

console.log(isSelected)

correctly outputs either true or false.

If we remove the destructuring variable reassignment, the code runs without errors:

<script setup lang="ts">
const { modelValue } = defineProps({
  modelValue: Boolean
})
console.log(modelValue)
</script>

<template>
  <div v-if="modelValue">Selected!</div>
</template>

The output of console.log(modelValue) remains consistent.
console.log(typeof modelValue) returns boolean.
console.log(typeof isSelected) also returns boolean.
So what exactly is causing the issue here?

Answer №1

First and foremost:

You cannot simply destructure props directly. The object returned by defineProps() is reactive, and breaking this reactivity by destructuring the object will result in the variables obtaining the current property values. To maintain reactivity, you must convert the object to refs using toRefs(), which can then be safely destructured.

Although I previously mentioned otherwise, there is now a feature known as "Reactive props destructure" (deprecated but available separately). This essentially means that the compiler transforms

const { prop: foo } = defineProps({ prop: String })
console.log(foo)

into

const __props = defineProps({ prop: String })
console.log(__props.prop)

Some individuals appreciate this change, while others find it confusing and counterintuitive. It's all subjective.

This modification tends to create confusion when typing. In the above example, even though foo appears to be a string, it actually possesses reactivity behind the scenes (unusual for a "bare" reactive primitive within a script block).


To simplify the first block of code:

<script setup lang="ts">
const { date1: inputDate1 } = defineProps({
  date1: String
})

const date1 = 'abc'
console.log(date1)
</script>

The issue here lies with:

Duplicate key 'date1'. May cause name collision in script or template tag. eslintvue/no-dupe-keys

Remember, props are automatically unwrapped in the template. They are accessible much like properties on window without explicitly stating window.; they exist at the top-level scope.

Since both the props and your defined variable share the same name (date1), conflicts arise due to ESLint's warning about possible collisions.

In your revised example:

const date2 = 'abc'
console.log(date1)

This leads to another error:

Cannot find name 'date1'. Did you mean 'date2'? ts(2552)

The reason behind this error is that props are only auto-unwrapped within the template context, not within the script itself. Therefore, date1 remains undefined in the script.


In addition, the line console.log(date1) displays the correct value during runtime.

While the output reflects the initial prop value, it lacks reactivity; the console.log() would not update even if it were. (There is partial reactivity involved, as discussed earlier.)


Addressing the next error:

[Vue warn]: Property "isSelected" was accessed during render but is not defined on instance.

I personally am unable to replicate this specific error message.

Perhaps it was a transient HMR glitch?


Without knowledge of your exact Vue version or configuration, I cannot delve further into the unrepeatable errors. If needed, share the complete code, configurations for replication, and preferably a link to a tool like Vue Playground or StackBlitz for better assistance.

During testing, I created a Vue Playground where you can experiment and view the compiled outcome.

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

Ancient queries carry the weight of time

Extremely ancient, very old, incredibly aged beyond belief ...

Utilizing mustache template strings within the href attribute in VueJS

How can I incorporate a mustache inside an href attribute within the context of Vue.js? After researching various solutions, I attempted to apply them to my code. Mustache inside an href How to pass a value from Vue data to an href? Reddit thread on us ...

Creating a Route in Angular 2 for a Component other than the one initialized with the bootstrap function

I am currently in the process of working on a project involving Angular2. If you are interested in understanding why I need to do what I am about to explain, please take a look at this issue. The main component in my project is called AppComponent and it ...

Next.js: Generating static sites only at runtime due to getStaticProps having no data during the build phase, skipping build time generation

I am looking to customize the application for individual customers, with a separate database for each customer (potentially on-premise). This means that I do not have access to any data during the build phase, such as in a CI/CD process, which I could use ...

Webpack is having trouble identifying Node's process module

It has been more than ten years since I last worked with JavaScript, but recently I had an idea for an app that would be best implemented as a NodeJS app. As I delved into the modern JS ecosystem, like many others, I found myself thoroughly confused, haha. ...

What steps can I take to prevent receiving the error message "Certain components in XXX are not associated with the entity" in Strapi?

User I am facing an issue with my application's endpoint for adding a like to a post. The endpoint is supposed to receive the user id who liked the post and insert it, along with the number of likes (not crucial at this moment), into a database. To ac ...

Creating components with the viewContainerRef in Angular2 is functioning as expected

When attempting to load a dynamic component into the root component using viewContainerRef.createComponent, I encountered an issue where it appended to the wrong place. https://i.stack.imgur.com/lF1yT.png Here is my code: -----app.compoment.ts----- exp ...

What is the best way to access JavaScript built-ins in Typings when faced with name conflicts?

I am currently in the process of updating the Paper.js Typings located on GitHub at this repository: github.com/clark-stevenson/paper.d.ts Within Paper.js, there exists a MouseEvent class, which is not an extension of JavaScript's MouseEvent, but ra ...

Highchart displays results for each individual line without the use of commas

I am interested in creating a chart using Highchart with three lines. The first two lines will display data similar to [4.12, 3.34, 5.45] / [3.45, 5.45, 3.23], while the third line should be displayed without any commas, showing results like [7, 4, 2]. Can ...

retrieve the status of a checkbox in a dynamically generated element

I'm currently working on integrating the YouTube API into my app in order to display a dynamic list of cards. The cards are stored in a variable and then added to a playlist container using an each function. Each card contains a toggle switch for use ...

Adjust jqGrid dimensions automatically as browser window is resized?

Does anyone know of a method to adjust the size of a jqGrid when the browser window is resized? I attempted the approach mentioned here, but unfortunately, it does not function correctly in IE7. ...

Display only alphabetic characters in the text field

I have a jQuery function that I am working on: $('#contact_name').on('input', function() { var input=$(this); var re =/^[A-Za-z]+$/; var is_email=re.test(input.val()); if(is_email) { } else { } }); This function is targeted at the fol ...

Issue with expanding TileLayer using TypeScript 2.0 and Angular 2: Unable to implement Leaflet Leaflet

Trying to incorporate the Microsoft Map API into my app has been a challenge, especially when I encounter errors like the one below when calling L.tileLayer.extend: Here is the snippet of my code: import { Component, OnInit } from '@angular/core&apo ...

Tips for effectively utilizing the updateAxisPointer function in the latest version of vue-echarts (v4.1)

Version 3 allows for direct use of the echarts functions and events, with the ability to override event functions like const updateAxisPointer = function(event)... However, I am struggling to implement this in version 4. You can find more information about ...

A guide on choosing a custom button color and automatically reverting to its original color when another button is clicked

I have a collection of 24 buttons, all in a dark grey (#333333) shade. Whenever I click on one of the buttons, it changes to a vibrant blue color (#0099ff), which is functioning correctly. However, when I proceed to click on another button, the previous ...

Encountering a Typescript issue while trying to access two distinct values dynamically from within a single object

Currently, I'm developing a component library and facing an issue with a TypeScript error: An Element implicitly has an 'any' type due to the expression of type 'levelTypes | semanticTypes' being unable to index type '{ level1 ...

How can we determine the total character count of a file that has been loaded into a textarea

I have a textarea where I can count the number of characters as I type. function calculateCharacters(obj){ document.getElementById('numberCount').innerHTML = obj.value.length; } <textarea name="textField" id="my_textarea" class="text_edit ...

Step-by-step guide on transforming a raw hexadecimal image into an HTML img tag

I have a raw hexadecimal representation of an image, such as: "FF00FF00FF00" Each pair of letters represents the color of one pixel. For example, in this case it is 6 pixels alternating between white and black, forming a 2x3 pixel grid (width x height). ...

Difficulty encountered while implementing Ajax POST in CodeIgniter

I've been working on a project similar to a ticket system that occasionally requires lengthy answers. When using CKEDITOR in the answer area, the agent's changes are automatically saved to the database using Json GET. However, I encountered an er ...

Is there a way to rotate a div without utilizing the "transform" CSS property?

I am currently utilizing a plugin from the SVG library to render graphics within a div (). However, I am encountering an issue when attempting to rotate it using the "transform" property. The rotation is purely visual and does not alter the X and Y axes of ...