What is the process for incorporating a dynamic component within a Vue component that is generic?

There's a "calendar" component in my project that needs to consume data from the caller and display all the days in a month. If there is data for a particular day, I want to show another component inside it. The problem is that the calendar component doesn't know what type of component it should use for each day slot.

I initially thought I could utilize a Vue3 generic component like this:

  • The data would be passed as a prop with a type of Record<string, T[]> (where the key follows the format Y-m-d)
  • The desired component would be passed as a prop with a type of DefineComponent<T>
// Your code example here

Despite working on the browser, the TypeScript compiler throws errors:

Your compiler error messages here

Play around with this Vue playground that showcases how the component is used

Can anyone guide me on the correct way to define types in order for the compiler to validate data against props for the component?

Answer №1

Interactive Demo

The functionality of the Component type is exemplary:

Calendar.vue

<script setup lang="ts" generic="T extends Record<string, any>">
import {type Component, computed, ref} from "vue";
import CalendarDay from "./CalendarDay.vue";

type Props<T> = {
    data: Record<string, T[]>,
    component: Component<T>,
    labelFn: (length: number, date: Date) => string,
};

...

This allows for utilization without predefined types:

<script setup lang="ts">
import Calendar from './Calendar.vue';
import SessionLink from "./SessionLink.vue";

//type Props = {days: Record<string, Array<InstanceType<typeof SessionLink>['$props']>>};
const props /*: Props */ = {
  days: {
    "2024-08-31": [
        {
          some: 'some',
          data: 'data'
        }
    ]
  }
}

function label(count: number, date: Date) {
    return `${count} sessions on ${date.toLocaleDateString()}`;
}
</script>

<template>
  <Calendar :data="props.days" :component="SessionLink" :label-fn="label" />
</template>

If incorrect types are provided, errors will be displayed for the :component, for more precise management, utilize

type Props = {days: Record<string, Array<InstanceType<typeof SessionLink>['$props']>>};

this will catch any mismatches in the data types.

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

Stopping HTTP client calls in OnDestroy hook of an Angular Service

Is it possible to automatically unsubscribe from an http call in an Angular service using the ngOnDestroy hook? Just to note, I am already familiar with using the rxjs 'take' operator or manually unsubscribing from the service within the compone ...

Tips for enabling type inference to function on a code snippet

Here is a simplified version of the code snippet: export abstract class Scheduler<TPayload> {} export interface EventKey<T> extends Symbol {} export type SystemSpecification<TPayload> = ( args: { /** The value provided by current ...

What is the best way to retrieve an object within an array using ng-repeat?

I'm encountering an issue with using ng-repeat in my development project. I am working with Ionic 2, utilizing TypeScript and HTML5. I have created an array of Objects where I need to access its attributes. The error message "cannot read property c.ge ...

Vue.js attempting to deactivate the global navbar and footerbar components while on specific routes

Here's the code snippet that allows for a different header bar to replace the standard header on a specific route: HeaderBar Code: <v-app-navbar> <header v-if="DesktopHeader"> content </header> <head ...

Is there a way to identify and retrieve both the initial and final elements in React?

Having an issue with logging in and need to retrieve the first and last element: Below is my array of objects: 0: pointAmountMax: 99999 pointAmountMin: 1075 rateCode: ['INAINOW'] roomPoolCode: "ZZAO" [[Prototype]]: Object 1: pointAmoun ...

Express is encountering an issue where it is unable to interpret the property 'name' of an undefined element coming from

I am attempting to create a fullstack application using Node.js and Angular with Material UI. I have encountered an issue while working on my web resource management application. Currently, I am facing an error during the registration and data submission ...

Guide: Updating Favicon.ico and Page Title in Vue Using Webpack

After setting up my project using vue-cli with 'vue init webpack project-name', I am struggling to customize the page title and favicon. Despite my efforts, the page title remains as 'Vue App' and the favicon continues to display the Vu ...

What is the best way to prevent a directory containing mock files from being included in a webpack build using vue.config.js?

In the root directory, I have a folder named mock that contains mock data used for running the app in development mode. However, when I build the app for production using vue-cli-service build, this folder gets included in the bundle, which increases the s ...

Using AJAX to fetch nested lists in Vue.js

Currently, I am attempting to replicate a vuejs nested list instance found on JSFiddle, with the added feature of AJAX integration: JSFiddle Example I have my PHP setup as follows: $todos = array( 'todos' => array( array( ...

The FOR UPDATE clause is not functioning as intended in the SELECT query

I have been working on isolating my database to prevent multiple servers from reading or updating data in the same row. In order to achieve this, I have structured my query like so: SELECT * FROM bridge_transaction_state as bridge WHERE bridge.state IN (&a ...

Vuelidate is failing to display the accurate error messages

Exploring vuelidate for the first time has been an interesting journey. I found that while following some of the tutorial examples in their documentation, my code was showing errors even before I started typing. Strangely, the error messages were not accur ...

Trouble arises when attempting to correctly implement Vue multiselect

Struggling to create a dropdown with vue-multiselect and encountering an issue. After selecting the initial option, everything works smoothly. However, once I choose another option, the previously selected one disappears as well. Here is the code snippet I ...

Is there a way for me to capture the text of the label that encloses my checkbox input?

Within my section-filter Vue component, the labels are populated using v-for and text from a "content" array in the data option. When a user interacts with the checkbox, I aim to retrieve both the value of "checked" (already achieved) as well as the text f ...

Angular validation with input binding using if statement

I have developed a reusable component for input fields where I included a Boolean variable called "IsValid" in my typescript file to handle validation messages. Here is the code from my typescript file: export class InputControlsComponent implements OnIn ...

Executing an asynchronous call in the created() lifecycle hook of a Vue component

In order to call the method below in the created() lifecycle hook, I need to mark created() as async. According to Vue documentation, created() is executed synchronously. Does Vue Framework automatically await on created() to prevent any race conditions? ...

Angular 6 Calendar Template issues with parsing: Unable to link to 'view' as it is not recognized as a valid property of 'div'

I am in the process of developing an application that utilizes this angular calendar. My tech stack includes Angular 6 with AngularFire2 and Firebase. Below is my app.module.ts file: import { BrowserModule } from '@angular/platform-browser'; imp ...

When attempting to fetch JSON data using the Angular 2 `http.get()` method, the data returned is undefined and the component does not reflect any

My http-data.service is set up to accept json for output in the component template. Initially, the console displays that the first few calls return undefined, while subsequent calls start returning json. However, upon checking the component, it is evident ...

Is it feasible to broaden an interface in Typescript without including a specific type?

import React from "react"; interface a_to_e { a?: string; b?: string; c?: string; d?: string; e?: string; } interface a_to_e_without_c extends a_to_e { // I want to include properties a~e except for c } function Child(props: a_to_e_without_c ...

Type aliases using generics may demonstrate varying behaviors from type aliases without generics

Here is a code snippet to consider: type TestTuple = [ { test: "foo" }, { test: "bar"; other: 1; } ]; type Foo<Prop extends string> = TestTuple extends Record<Prop, string>[] ? true : fal ...

Troubleshooting Angular 7 Build Failure: Missing Typescript .d.ts Declaration Files for Ahead-of-Time Compilation

I have encountered difficulties in building my Angular 7 application after upgrading from v6. When I use ng build, everything runs smoothly. However, when I try either ng serve --aot, ng build --aot, or ng build --prod (which also includes aot), an error ...