In Vue3, automatically infer a type for a slotProp based on the modelValue

In simplifying the component I aim to create, I have created the following code structure:

// MyComp.vue

<script setup lang="ts">
import { PropType, defineProps, defineEmits } from 'vue';

const props = defineProps({
    modelValue: {
        type: Array as PropType<unknown[]>,
        required: true,
    },
});

const emit = defineEmits({
    updateModelValue: (value: unknown[]) => true,
});
</script>

<template>
    <div v-for="(item, index) in modelValue" :key="index">
        <slot :item="item" :index="index"></slot>
    </div>
</template>
// Parent.vue

<script setup lang="ts">
import { ref } from 'vue'
import { MyComp } from '.';

const myArray = ref([
    {
        name: 'A',
        id: 1,
    },
    {
        name: 'B',
        id: 2,
    },
]);

</script>

<template>
    <div>
        <MyComp v-model="myArray">
            <template #default="{ item }">
                <!-- item is of type unknown - type not inferred :( -->
                <div>{{ item }} </div>
            </template>
        </MyComp >
    </div>
</template>

The issue lies in the fact that the type of item does not get inferred, resulting in a lack of IntelliSense support.

How can this be resolved effectively?

(Additional details were added to comply with StackOverflow requirements)

Answer №1

It appears that you have explicitly set the type of your array item to unknown. At this point, TypeScript may not have anything more to infer.

If you are working with Vue version 3.3 or higher, you can utilize generic components:

// MyComp.vue

<script setup lang="ts" generic="T">
import { PropType } from 'vue';

const props = defineProps({
    modelValue: {
        type: Array as PropType<T[]>,
        required: true,
    },
});

const emit = defineEmits({
    updateModelValue: (value: T[]) => true,
});
</script>

This approach will correctly infer types, as demonstrated in this playground

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

Discovering subtype relationships in JSON with TypeScript

Consider the scenario where there are parent and child typescript objects: class Parent { private parentField: string; } class Child extends Parent { private childField: string; } Suppose you receive a list of JSON objects for both types via a R ...

Having trouble getting Vue UI to install correctly on my new project using Laravel Framework version 8.83.7

I am having trouble installing Vue in my Laravel project. Here are the steps I follow: Run composer require laravel/ui Install Vue using: php artisan ui vue Install Vue with authentication using: php artisan ui vue --auth Then run: npm install ...

Discover the seamless transformation of a class definition into a Vue 3 component definition utilizing the dazzling 'tc39' decorators

The proposed API in the tc39/proposal-decorators repository is significantly different from the previous decorators API. Although TypeScript 5 doesn't fully support the new API yet, it's only a matter of time before the old API becomes deprecated ...

Firebase 9: Access Denied - Realtime Database Security Breach

Currently working on a chat application using Vue3 and Firebase 9, everything is functioning well except for the delete function. An error message appears in the console: @firebase/database: FIREBASE WARNING: set at /message/-MzxBJXezscUw4PbEAys failed: pe ...

Launching a Web Application developed using the vue framework

Hey everyone, I recently created a web application using the Vue framework. To prepare for deployment, I followed the instruction to get a dist file by running: npm run build Once I obtained the dist file, I uploaded the entire application folder to File ...

Simulating Express Requests using ts-mockito in Typescript

Is there a way to simulate the Request class from Express using ts-mockito in typescript? I attempted the following import { Request, Response } from "express"; const request = mock(Request); const req: Request = instance(request); but encou ...

Typescript is throwing a Mongoose error stating that the Schema has not been registered for the model

I've dedicated a lot of time to researching online, but I can't seem to figure out what's missing in this case. Any help would be greatly appreciated! Permission.ts (This is the Permission model file. It has references with the Module model ...

The member 'email' is not found in the promise type 'KindeUser | null'

I'm currently developing a chat feature that includes PDF document integration, using '@kinde-oss/kinde-auth-nextjs/server' for authentication. When trying to retrieve the 'email' property from the user object obtained through &apo ...

Troubleshooting the issue of file URL chunks in Laravel and Vue.js

I'm currently working on a web application using Laravel and Vue. I have deployed the application to the following route on the host: https://novintech.info/panel Everything seems to be fine, except that the chunks file is referencing the wrong path ...

What is the most effective approach for annotating TypeScript abstract classes that are dynamically loaded?

I am in the process of developing a library that allows for the integration of external implementations, and I am exploring the optimal approach to defining types for these implementations. Illustration abstract class Creature { public abstract makeN ...

The Store Variable in Nuxt 3 is not being updated

Struggling to get my store functioning properly. I'm familiar with creating a store using vue 3, but with Nuxt 3, my values don't update as expected. Here's my function for adding something to the store: <script setup> function addW ...

Troubleshooting Vue 3 component rendering issues in Laravel 8

My setup includes a basic blade file with a component embedded within: <section> <h1>Carousel</h1> <carousel :slides="@json($data->slides)"> </carousel> This is how the component is structured: <templa ...

Is it true that a TypeScript derived class is not allowed to have identical variable names?

Why is it not allowed for TypeScript derived classes to have the same variable name, even if these members are private? Is there another way to achieve this, or am I making a mistake? class ClassTS { private nom: string = "ClassTS"; ...

Load elements in Vue dynamically when a drop-down selection is made

I am looking to implement a functionality where on initial page load, there is a single drop-down field displayed. When an item is selected from this drop-down, I want another drop-down to appear with the same items: After repeating this procedure: I don ...

Tips for updating or replacing items in a JavaScript array

Explaining what I need, here's the code snippet: Everything works smoothly when adding a product to the items array if it does not already exist (based on id). However, if it does exist, I only want to update the item. The distinction is based on the ...

Understanding eventBus value listening in Vue.jsWould you like to learn how to

I've encountered an issue while trying to retrieve the search input value. Below is how I'm sending values using the event bus: import eventBus from "../../../services/eventBus"; export default { name: "Navbar", data() { return ...

How can I display a new module in Angular without navigating to it?

After following the tutorial at https://angular.io/guide/lazy-loading-ngmodules#create-a-feature-module-with-routing I set out to create the following: My goal is to have a dedicated module for all customer-related components accessible through the /cust ...

Using Typescript and Next.js to handle error messages returned from Axios responses

My Next.js application makes an API call to validate a registration form. The server returns error messages in the following format: {"message":"The given data was invalid.","errors":{"email":["The email has alr ...

Evaluating Vue performance with an extensive collection of objects

I'm faced with a challenge involving a lengthy list of 460 items stored in "harvesters". Below is my Vue code snippet for filtering this list: computed: { searchHarvesters() { var vm = this; let searchTerm =this.searchInHarvesters.toL ...

Minimizing the distance between radio label rows

I'm working on a radio button with a label spanning two lines, but the whitespace between the lines is too much. I need to reduce it. Here's my code example: <label for="reg-promo"> <input type="radio" name="promotion" id="registerPr ...