How can Enums be utilized as a key type for transmitting properties in Vue?

After stumbling upon a helpful method on Stack Overflow that demonstrated how to use an enum to define an object, I decided to implement this in my Vue project.

export enum Options {
  randSize = 'randomSized',
  timer = 'showTimer',
  randAngle = 'randomAngle',
  colours = 'multiColour',
  cardSize = 'cardSize',
  numCards = 'numCards'
}

(parent component):

import { Options} from './util'
let options : {[key in Options]: number | boolean} = {
  [Options.randSize]: true,
  [Options.timer] : false,
  [Options.randAngle] : true,
  [Options.colours] : true,
  [Options.cardSize] : 8,
  [Options.numCards] : 20

}

I also found a solution (credit to this post) for changing option values:

function changeOption( option: string, value: number | boolean) {
  options = {...options,[option]:value}
}

However, when attempting to utilize these options as a component property, the enum is not recognized:

(parent template):

      <game-options 
        :options = "options"
        @done-setup = "gameStarted=true"
        @change-options="changeOption"
      >
      </game-options>

(child component):

import { ref, onMounted } from 'vue'
import { Options} from '../util'

const props = defineProps<{
  options: {[key in Options]: number | boolean}
}>()

onMounted(() =>{
  console.log(props.options);
  let foo = props.options.randSize;
})

This results in an error message stating:

Property 'randSize' does not exist on type '{ randomSized: number | boolean; showTimer: number | boolean; randomAngle: number | boolean; multiColour: number | boolean; cardSize: number | boolean; numCards: number | boolean; }'.ts(2339)

What steps can be taken to resolve this issue?

Answer №1

The source you referenced explains that

inside Enum translates to enum values and keyof typeof to enum keys.

Upon examining sizeOption in the given enum

export enum Choices {
  sizeOption = 'randomSize',
  ...
}

the key is sizeOption and the value is randomSize. Therefore, for

{[key in Choices]: number | boolean}
, the property will be named randomSize, not sizeOption.


When dealing with more intricate types, it's important to remember that there are certain syntax constraints, notably, defineProps cannot perform actual type analysis, it only resolves syntax. It may not always be clear where one aspect ends and another begins. In this scenario, defineProps might not ascertain the type, Vue will simply recognize an options prop without understanding its type. However, IDEs can provide type completion, inferring the complete type and offering type errors and auto-completion (check out sandbox). Although Vue won't raise type errors. If this is satisfactory, everything should function smoothly.

Nevertheless, consider that:

const properties = defineProps<{
  [key in Options]: number | boolean
}>()

would be invalid, as Vue struggles to interpret the precise structure of the type.

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 function is not defined for this.X in TypeScript

I am currently developing an application using Angular 6. Within my app, I have the following code snippet: import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: ...

Learn how to import a stylus file globally in Vite build tool

Recently, I decided to use vite for building a new vue application. However, I encountered some difficulties when trying to globally import a stylus file in my vite.config.js. I followed the code examples provided in the vite documentation: export default ...

Received a 'Vue error: Redundant navigation to current location prevented' when attempting to refresh the page with updated parameters

I'm attempting to refresh the page with new parameters when the state changes: @Watch('workspace') onWorkspaceChanged(o: Workspace, n: Workspace){ if(o.type === n.type && o.id === n.id) return; this.$router.push({name: this.$rout ...

What is the best way to determine if a local storage key is not present?

By applying the if condition below, I can determine whether or not the local storage key exists: this.data = localStorage.getItem('education'); if(this.data) { console.log("Exists"); } To check for its non-existence using an if conditi ...

Setting up ReactJS and TypeScript in a fresh MVC5 project from scratch

After extensively trying out various tutorials, I have yet to successfully run a basic MVC5 project using TypeScript and ReactJS. For reference, I have created these projects from scratch in Visual Studio 2015 with .NET 4.6.1, using the ASP.NET Web Applic ...

Executing methods sequentially in the ngOnInit lifecycle hook consecutively

Working with Angular15 has presented me with a challenge. In my app.component.ts file, I have two methods: “ngOnInit()”, as shown below. public ngOnInit(): void { this.getToken(); this.UserLoggedIn(); } I am looking to run the above two functions in ...

Using Angular to include more than two parameters in an HTTP GET request

Currently, I am developing an application that requires downloading a file upon clicking a button within a template. The screen displays multiple files, each with its own corresponding button. I need to send the index number of the array to Angular and pas ...

When using vue-router push, the first page should not be concealed even if the data array is extensive

After navigating from Home.vue to History.vue using this.$router.push("/history/" + fileid);, a socket.io request is triggered in the created or mounted lifecycle hook which fetches a large amount of data. The rendering process, especially with v-for, take ...

The error message "Module 'electron' not found" is commonly encountered when working with Electron and TypeScript

Hey there! I'm having some trouble with Electron not supporting TypeScript on my setup. I'm using vscode 1.16.1 and here is an overview of my package.json: { [...] "devDependencies": { "electron": "^1.6.13", "ts-loader": "~2.3.7", ...

How can you set a checkbox to be selected when a page loads using Angular?

On page load, I need a checkbox to already be 'checked', with the option for the user to uncheck it if they want. Despite trying to add [checked]="true" as recommended in some Stack Overflow answers, this solution is not working for me. <label ...

What are the steps to validate a form control in Angular 13?

My Angular 13 application has a reactive form set up as follows: I am trying to validate this form using the following approach: However, I encountered the following error messages: Additionally, it is important to note that within the component, there ...

Issue with CORS policy preventing Laravel 9 from running properly (XMLHttpRequest access blocked)

I am currently working on developing a frontend web application using Vuejs, and I need to fetch data from an API built with Laravel 9. However, when trying to access the data from the frontend, I encountered the following CORS-related error in the browser ...

Unable to utilize console.log and alert functions within the Next.js application

I'm currently facing a problem in my Next.js application where the console.log and alert functions are not functioning as intended. Despite checking the code, browser settings, and environment thoroughly, pinpointing the root cause of the issue remain ...

Vue.js Webpack NPM command for enabling live reload and watching

Ever since upgrading from node version 8 to 14 and npm version 6 to 7, I've been facing an issue. Each time I try running the command below: npm run watch I encounter the following error: [webpack-cli] Invalid configuration object. Webpack has been i ...

Incorporating an offset with the I18nPluralPipe

Having trouble with my multiselect dropdown and the text pluralization. I attempted to use the I18nPluralPipe, but can't seem to set an offset of 1. ListItem = [Lion, Tiger, Cat, Fox] Select 1 Item(Tiger) = "Tiger", Select 3 Item(Tiger, Cat, Fox) = ...

How can I reset a CSS position sticky element using JavaScript?

I have created a page where each section fills the entire screen and is styled using CSS position: sticky; to create a cool layered effect. Check it out here: https://codesandbox.io/s/ecstatic-khayyam-cgql1?fontsize=14&hidenavigation=1&theme=dark ...

Missing data list entries for next js server actions

After successfully running my add function, I noticed that the data I added earlier is not being reflected in the list when I check. import React, { useEffect, useState } from "react"; import { createPost } from "./actions"; import { SubmitButton } from ". ...

Upon executing the `npm start` command, the application experiences a crash

When I tried following the steps of the Angular quickstart guide, I encountered some errors after running "npm start". Here are the errors displayed: node_modules/@angular/common/src/directives/ng_class.d.ts(46,34): error TS2304: Cannot find name 'Se ...

Using square brackets to reference custom class names in Tailwind CSS does not function properly within the context of a Nuxt application

I recently developed a Nuxt application with TailwindCSS, but I'm facing an issue with the square bracket notation from Tailwind. When I use the following div => <div class="h-[155px] bg-red-300">some text</div> the h-[155px] ...

Implementing mixin functions in vue.router routes with Vue.js

Is there a way to dynamically change the title of the window based on each route? I have included a meta: { title: ... } object in each child object within the routes: []. Here is an example: routes: [ { path: 'profile/:id', name: 'Prof ...