Tips on implementing v-bind with multiple object arrays in Vue3 using TypeScript

Working with vue3 + vite + ts, I customized a text editor using tiptap. However, when I try to access item.type , item.icon, or any other item attributes, they all show 'error'.

This indicates that ToolbarItem | Divider does not have certain attributes:

item.type => Property 'type' does not exist on type 'ToolbarItem | Divider', Property 'type' does not exist on type 'ToolbarItem'
,

In the parent component code:

<template v-for="(item, index) in items" :key="index">
    <div v-if="item.type === 'divider'" class="divider" :key="`divider${index}`" />
    <Child v-else :key="index"
            :icon="item.icon" :title="item.title"
            :action="item.action" :isActive="item.isActive"/>
</template>
interface ToolbarItem {
    icon: string,
    title: string,
    action: Function,
    isActive?: Function
}

interface Divider {
    type: string
}

const items: Array<ToolbarItem | Divider> = [
    {
        icon: 'bold',
        title: 'Bold',
        action: () => props.editor.commands.toggleBold(),
        isActive: () => props.editor.isActive('bold'),
    },
    {
        type: 'divider'
    },
    ...
]

In the Child component code:

interface ToolbarButtonProps {
    icon: string,
    title: string,
    action: Function,
    isActive?: Function
}

const props = defineProps<ToolbarButtonProps>()

I am looking for a way to inject items separately into the div or Child components to avoid the error messages.

Answer №1

that say ToolbarItem | Divider not have each other attributes

As indicated by the error message, the objects in your array lack similar properties. JavaScript permits accessing properties that are not present in an object. For example:

const fruit = { shape: 'round', color: 'red' };
console.log(fruit.size); // undefined

While JavaScript allows this behavior, it is not recommended as it can lead to confusion and readability issues in the code. TypeScript identifies this problem and raises a complaint.

To resolve the TypeScript error, you can rethink how you structure your template. Consider the following approach:

<template v-for="(item, index) in items" :key="index">
    <div v-if="item.type === 'divider'" class="divider" :key="`divider${index}`" />
    <Child v-else :key="index"
            :icon="item.icon" :title="item.title"
            :action="item.action" :isActive="item.isActive"/>
</template>

By modifying the code in this way, you can eliminate the need for a standalone "divider" element in the items array and simplify the rendering logic for Child components.

For a more concise structure, consider the revised template below:

<template>
  <section v-for="(item, index) in items" :key="index">
    <Child
      :key="index"
      :action="item.action"
      :icon="item.icon"
      :isActive="item.isActive"
      :title="item.title"
    />
    <div
      v-if="index < items.length"
      :key="`divider${index}`"
      class="divider"
    />
  </section>
</template>

This revised structure eliminates the need for explicitly checking and rendering the Child component based on a specific condition.

const items: Array<ToolbarItem> = [
  {
    icon: 'bold',
    title: 'Bold',
    action: () => props.editor.commands.toggleBold(),
    isActive: () => props.editor.isActive('bold'),
  },
  ...
]

For better clarity and efficiency, you can refer to this example.

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

Managing multiple `ng-content` slots in Angular can be a daunting task. Here

I am facing an issue with a component where I have declared an input as follows: @Input() isOverlay: boolean The template html for this component looks like this: <ng-template *ngIf="isOverlay" cdkConnectedOverlay [cdkConnected ...

What is the best way to include a Web Service within an export variable in Angular 2 using TypeScript?

Is there a way to incorporate JSON data retrieved from the server into the export var HEROES: Hero[ ] function? Here is the link: https://angular.io/resources/live-examples/toh-5/ts/eplnkr.html In app/mock-heroes.ts, you will find the following data, im ...

Angular promise not triggering loop creation

I am encountering an issue with a particular function handleFileInput(file: any) { let promise = new Promise((resolve, reject) => { this.uploadFileDetails.push({ filename:this.FileName,filetype:this.FileType}); ... resolve(dat ...

Error message received when making an API call in React Native for Android and saving the response to a local database: 'Error: Network

Despite using axios and promises to make a call to a local database API, I am facing difficulties reaching the endpoint as I constantly receive a 'Error: Network Error' feedback in the console without any further explanation on the root cause of ...

Error TS7053 occurs when an element is given an 'any' type because a 'string' expression is being used to index an 'Object' type

When attempting to post data directly using templateDrivenForm and retrieve data from Firebase, I encountered the following type error message. Here are the relevant parts of my code: // Posting data directly using submitButton from templateDrivenForm onC ...

Tips for accessing the type of a nested union in TypeScript

My graphql codegen has produced this type for me: export type GetOffersForMembershipQuery = { __typename?: "Query"; offers: | { __typename?: "BaseError" } | { __typename?: "QueryOffersSuccess"; data ...

What benefits does Observable provide compared to a standard Array?

In my experience with Angular, I have utilized Observables in the state layer to manage and distribute app data across different components. I believed that by using observables, the data would automatically update in the template whenever it changed, elim ...

Obtain a controller's reference from a callback by utilizing TypeScript

Implementing a simple controller that utilizes a directive/component and passes a function as binding. However, when the function is called, there is no reference available to access any of the controller class services. Within the "public onTileClicked" ...

Encountering an issue with importing an enum: An error is triggered stating 'Variable implicitly has type 'any' in certain areas where its type remains undetermined.'

When I define simple enums in the same file, everything works fine. However, exporting/importing them causes numerous compilation errors related to types. It seems like the issue only arises when defining enums in a separate file, pointing towards a proble ...

Reattempting a Promise in Typescript when encountering an error

I am currently working on a nodeJS application that utilizes the mssql driver to communicate with my SQL database. My goal is to have a unified function for retrieving a value from the database. However, in the scenario where the table does not exist upon ...

Unraveling the mysteries of Typescript with async await

I'm facing a peculiar issue in my code that I'm struggling to identify. try { const result = await somePromise.catch((err) => { console.log(new Date()); // displays time, t0 console.log('Stats', eventLoopStats.se ...

Is there a way to automatically extend my content to fill the space on the page below the Material UI AppBar?

I am currently using React and Material UI React to develop my application. My goal is to implement the AppBar component with content underneath, without causing the entire page to scroll. I want the content to occupy the maximum remaining height and the f ...

What is the reason for TypeScript allowing this promise chain without any compilation errors?

Although I am still relatively new to Typescript, I find myself grappling with a particular issue that has been perplexing me. I am unsure why the following code snippet triggers a compilation error: // An example without Promises (does not compile) funct ...

Tips for improving the slow compilation of the Next.js 14 development environment

Currently, I am tackling an issue with my Typescript - Next.js 14 Application where the compilation process in the development environment is taking excessive time, sometimes up to 60 seconds. What steps can be taken to resolve this problem and optimize t ...

Adding to object properties in Typescript

My goal is to dynamically generate an object: newData = { column1: "", column2: "", column3: "", ... columnN: "" } The column names are derived from another array of objects called tableColumns, which acts as a global variable: table ...

Creating click event handler functions using TypeScript

I encountered an issue when trying to set up an event listener for clicks. The error message I received was that classList does not exist on type EventTarget. class UIModal extends React.Component<Props> { handleClick = (e: Event) => { ...

The issue with APP_INITIALIZER is that it fails to resolve promises before moving on to other

I can't seem to figure out what's missing here. I hope it's just a minor issue. The problem I'm facing is that the APP_INITIALIZER isn't resolving completely. In my code, I have two services: AppSettingsService and SomethingServi ...

Setting up shortcuts for webpack using lerna and typescript

I have set up a repository to showcase an issue I am facing: https://github.com/vileen/lerna-webpack-typescript-aliases-issue (the app does not start properly, but that's not the main concern). The main question here is how can I enhance importing fr ...

Error: Name 'AudioDecoder' could not be located

In my current project using React and TypeScript with Visual Studio Code 1.69.2 and Node 16.15.1, I encountered an issue. I am attempting to create a new AudioDecoder object, but I keep getting an error message stating "Cannot find name 'AudioDecoder ...

Angular - Execute function every 30 seconds while considering the duration of the function execution

In my Angular 7 application, I am utilizing RxJS to handle asynchronous operations. My goal is to retrieve a list of items from an API endpoint every 30 seconds. However, there are times when the request may take longer than expected, and I want to ensure ...