Exploring Vue.js 3: Validating props with a custom type definition

I am currently working on a Vue.js 3 and Typescript single page application project.

The issue I am facing involves a view and a single file component. In the People.vue component, data is fetched from the backend and displayed in multiple instances of the PersonRow.vue component using v-for. Even though the types of data properties are explicitly defined, a warning appears in the browser console:

[Vue warn]: Invalid prop: Type check failed for prop "person". Expected Person, got Object

While everything seems to be functioning correctly, I could resolve the warning by changing the property type in PersonRow.vue to Object, but I prefer to have the type checks working accurately.

People.vue

<template>
  <div class="container">
    <PersonRow v-for="person in people" :key="person.id" :person="person" />
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Person, getPeople } from '../services/person'
import PersonRow from '@/components/PersonRow.vue'

export default defineComponent({
  components: {
    PersonRow
  },
  data () {
    return {
      people: new Array<Person>()
    }
  },
  mounted () {
    getPeople().then(
      response => {
        this.people.push(...response)
      })
  }
})
</script>

PersonRow.vue

<template>
  <div class="row">
    <div class="col">{{ person.givenName }}</div>
    <div class="col">{{ person.familyName }}</div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Person } from '../services/person'

export default defineComponent({
  props: {
    person: {
      type: Person,
      required: true
    }
  }
})
</script>

person.ts

export class Person {
  constructor (id: number, givenName: string, familyName: string) {
    this.id = id
    this.givenName = givenName
    this.familyName = familyName
  }

  id: number;
  givenName: string;
  familyName: string;
}

export async function getPeople (): Promise<Person[]> {
  const response = await fetch('https://api.example.com/people')
  return await response.json() as Person[]
}

Answer №1

Annotating Props

export default defineComponent({
  props: {
    person: {
      type: Object as PropType<Person>,
      required: true
    }
  }
})

Exploring further

A reminder from the documentation states: In addition, type can also be a custom constructor function and the assertion will be made with an instanceof check

However, to ensure its success, the object assigned to the prop needs to be instantiated using the new Person() constructor. The issue lies in the fact that your getPeople () function is not generating an array of Person instances - it simply converts an array of standard JS objects created with json() to Person[]. Casting types does not alter the runtime type of the object...

Answer №2

The term "person" does not fit within the established types in programming such as Array, Object, String, Number, Boolean, or Function. This is important to ensure that type checks are carried out accurately and effectively.

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

Having trouble getting a Vue carousel to work with a dynamic index, but there are no console errors popping up

I've been attempting to create a basic slider using Vue, but I'm having trouble with dynamically changing data based on the selected index. The issue seems to lie in how the index is being selected because the looped element fails to render when ...

Error encountered during module build in Vue loader version 17.0.0 with Webpack version 5.74.0

I am encountering an issue while trying to integrate vue-loader into my SPA VUE APP. The error message I'm receiving is as follows: ERROR in ./app2.vue Module build failed (from ./node_modules/vue-loader/dist/index.js): TypeError: Cannot read prope ...

How come I am unable to activate the input file using prop?

Attempting to access a selection of files by passing a prop to a component for convenience. Is there a method to achieve this? https://codepen.io/iliyazelenko/pen/RBejRV?editors=1010 The code snippet below does not meet my requirements: <input type ...

Creating an array object in TypeScript is a straightforward process

Working on an Angular 4 project, I am attempting to declare an attribute in a component class that is an object containing multiple arrays, structured like this: history: { Movies: Array<Media>, Images: Array<Media>, Music: Array<Medi ...

Utilize the fetch function within a React functional component

I have been experimenting with different methods to fetch data only once before rendering, but I am encountering some challenges: It is not possible to call dispatch in componentDidMount as there is a restriction that it can only be done in Functional c ...

Angular 2 rc5 component fails to load

After transitioning from Angular2 RC4 to RC5, I've been facing some issues. I can't tell if these problems are due to my errors or the transition itself. Here's how my app component looks: import {Component, OnInit} from "@angular/core"; im ...

Enhance your Vue.js experience with an improved method for monitoring values

My setup involves Vue CLI 3.11 (based on Node.js 12.10) and Google Chrome. I am trying to create a syntax that can bypass the watch function under specific conditions. However, I am struggling because Vue.js handles value changes differently compared to J ...

When utilizing the navigation.navigate function, react-navigation v6.0 may present an error message

The Challenge I'm Dealing With One issue I encountered is when I use navigation.navigate('XXXPage'), react-navigation version 6.0 displays the following error message. Argument of type 'string' is not assignable to parameter of ty ...

Retrieve information from a watcher through a Vuex getter

I am working with a namespace module that has a getter method called allItems(), which is used to retrieve an array of values from a normalized state. ... getters: { allItems(state, getters, { entities }) { return state.items.map(function ...

What is the process for importing a TypeScript module exclusively through typings without having to download it separately?

Currently, I am working on a widget for a website that is already utilizing jQuery and I am using TypeScript. The goal is to embed my output into the host website while taking advantage of the existing jQuery library loaded by the host site. In order to r ...

WindiCSS classes are not functioning properly within a Nuxt application

I've been encountering some difficulties with WindiCSS. The classes are not being applied to the elements as expected. I attempted to install an older version of Windi, but the issue persisted. I even tried switching to Tailwind instead of Windi, but ...

Error: The module '@angular/core' cannot be located

Currently, I am working on a simple Angular 2 project with NodeJS as the backend and my preferred editor is Atom. So far, I have successfully installed Angular2 (2.0.0-beta.17) and Typescript using npm. npm install angular2 npm install -g typescript Wit ...

The Vue.js website fails to load on Internet Explorer 11 due to compatibility issues

Package.json { “name”: “Chatwidget”, “version”: “0.1.0”, “private”: true, “scripts”: { “serve”: “vue-cli-service serve”, “build”: “vue-cli-service build”, “lint”: “vue-cli-service lint”, “deploy”: “rsyn ...

Tips for incorporating asynchronous page components as a child element in next.js?

Utilizing the latest functionality in next.js for server-side rendering, I am converting my component to be async as per the documentation. Here is a simple example of my page component: export default async function Home() { const res = await fetch( ...

saving user's scroll position in a Vue 3 app

Encountering an issue with my Vue application. It comprises more than 40 pages, and the problem lies in the browser caching the scroll position. As a result, when users navigate from one page to another, the browser displays the scroll position of the prev ...

Is MongoDB still displaying results when the filter is set to false?

I am currently trying to retrieve data using specific filters. The condition is that if the timestamp falls between 08:00:00 and 16:00:00 for a particular date, it should return results. The filter for $gte than 16:00:00 is working correctly, but the $lte ...

Can the type of a prop be specified in the parent component before it is passed down to the children components that utilize the same prop?

In my codebase, I have a component called NotFoundGuard. This component only renders its children if a certain condition is true. Otherwise, it displays a generic fallback component to prevent redundancy in our code. I am trying to figure out if there is ...

You have encountered an error: Uncaught TypeError - the function (intermediate value).findOne is not defined

Encountering an error when attempting to call the getStocks function from a Vue component. smileCalc: import User from "../models/user.js"; let userID = "62e6d96a51186be0ad2864f9"; let userStocks; async function getUserStocks() { ...

Ways to redirect to a different page following a successful execution of a mutation in React-query

I am facing an issue where a memory leak warning appears when I redirect to another page after a mutation. Despite trying various methods, I have not been able to find a solution. The specific warning message is: Warning: Can't perform a React state ...

What is the most efficient way to update data multiple times by mapping over an array of keys in a react hook?

My question might not be articulated correctly. I'm facing an issue with dynamically translating my webpage using Microsoft's Cognitive Services Translator. I created a react hook for the translator, which works well when I need to translate a si ...