Suggestions for enforcing type checking on props at compile time in Vue templates?

Vue in conjunction with Typescript enables the specification of types for props, allowing for more robust component development. For example, check out this discussion on Strongly typing props of vue components using composition api and typescript typing system

However, it seems that these prop type checks only occur at runtime. Let's consider a simple component with two props: a, and b. One is expected to be a number while the other should be a string with a specific validation condition (i.e., equal to hi)

<template>
  <p>{{a}}</p>
</template>

<script>
import {defineComponent} from 'vue';
export default defineComponent(
    {
        name: "TestComp",
        props:{
            a:number,
            b:{
                type: String,
                validator:(val)=>val=="hi"
            }
        }
    }
)
</script>

Visualize the misuse of this component where a has an incorrect type and b fails its validator:

<TestComp a="hi" b="ho"/>

The question arises: can we detect such bugs during compile time rather than waiting for runtime errors? By default, Vue only raises an error at runtime when encountering invalid props, displaying messages like

Invalid prop: custom validator check failed for prop "b"
.

After some online research, I stumbled upon an experimental Vetur feature that allows for prop type validation. However, this feature does not trigger the custom validator, hence missing issues similar to the one observed in prop b above.
Moreover, relying solely on Vetur may not be ideal as I prefer immediate compile-time errors for wrong prop typings.

Answer №1

When it comes to (a): Defining Types

The Typescript / Vue Template compiler does not have the capability to validate type definitions.

Why is that? Well, simply because the template compiler lacks access to the necessary type information.

However, there are ways to analyze this information externally to the standard template compiler. WebStorm offers a tool for this purpose.

As for (b): Validation Process

The validation process occurs during runtime, making it impossible to verify at compile time.

To ensure proper validation, one can define the exact type of the prop by adding it explicitly, allowing tools like WebStorm to conduct checks. While /** @type */ comments can be used as well, leveraging TypeScript is recommended for best results.

<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent(
    {
        name: "TestComp",
        props:{
            b:{
                type: String as PropType<"hi">,
                validator:(val)=>val==="hi"
            }
        }
    }
)
</script>

Answer №2

If you're looking to check Vue templates on compile, consider trying out vue-tsc from the Vite vue-ts preset. Initially, I was planning to use both Vite and Webpack for template type checking, but it appears that vue-tsc can handle this task independently. Nevertheless, opting for Vite CLI simplifies configuration since it offers a comprehensive TS setup, enabling us to easily integrate with our existing tsconfig file.

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

Utilize Object literal manipulation to include properties in a specific sequence

Working on a tool to generate Nassi-Shneiderman diagrams online, where each diagram is represented as an object literal with unlimited possible children. As I aim to add a sequence into the while loop following the first sequence, I encounter the challeng ...

Is the contenteditable feature working properly when updating PHP, SQL, and AJAX in the network?

Struggling with updating modified text to SQL using PHP and Ajax. Unsure if the issue lies in the data sent through Ajax or a problem within the PHP script. Below is my snippet from the HTML file: <tr> <td class="editingTab" contenteditable=&ap ...

Accelerating the Jquery/Json query速

Working with javascript/jquery for the first time has been quite a learning experience. I had to follow each step carefully, but I finally managed to get it working exactly how I wanted. My JSON file contains data formatted like this: [ { "Procedure ...

The checkbox linked to a Vector layer in Openlayers 3 seems to have no effect on its visibility

Help me debug my code where I am attempting to connect a checkbox to a vector layer's 'visible' property. I can't seem to figure out what's wrong, can you spot the error? Interestingly, this code successfully works for ol.layer.Ti ...

What causes certain images to have unspecified height and width measurements?

Currently, I am in the process of extracting image sizes from a website using a module called scraperjs. Most images have their height and width attributes defined, but some do not, resulting in the returned value being "undefined". How can I retrieve the ...

Steps for referencing an autogenerated id in a Firestore collection

I need assistance updating a 'progress' field in a document with an autogenerated ID (using Firestore) every time the progress button is clicked. https://i.stack.imgur.com/hZieN.png Despite my attempts, nothing seems to work. Here is the method ...

Attempting to transfer a JSON object from a frontend Form Input to an Express backend

Apologies for bringing up what may seem like a basic issue, but I've been searching extensively (even through axios' documentation) and haven't been able to pinpoint exactly what I need to resolve this issue. I have created a simple To-Do we ...

Ways to trigger javascript following each ajax or complete request

I have a jQuery function that attaches a click event to specific elements, as shown below. $(".alert-message .close").click(function(e) { $(this).parent().fadeTo(200, 0, function() { $(this).slideUp(300); }); e.preventDefault(); }) ...

I am looking to transmit a JWT token to my backend using next-auth

In my current project using Next.js, I have implemented authentication with next-auth. This project follows the MERN stack architecture. I am facing an issue where I need to retrieve the JWT token and send it to my backend server using next-auth along wit ...

Obtain serialized information from php using ajax

I am currently working with a php script that returns serialized data. I am trying to retrieve this data using the $.ajax() method from jQuery 1.7. You can find an example here. $.ajax({ url: 'http://input.name/get.php?do=lookup' + '&am ...

Implementing an array of objects within a Vue method

I currently have an object called "Sorteio" which contains a vector of objects named "Resultado", consisting of 6 Resultados. The way I am creating instances of them is as follows: saveSorteio() { var data = { loteria: this.sorteio.loteria, ...

Express.js router defining a module issue

I have encountered a problem while working on my Express.js project. The 'slug' variable that I defined in app.js is not being recognized in the controllers within the router. Is there a way to define these variables in a central location, as I w ...

Enhance your dynamic content with jQuery/AJAX through customized CSS styling

Below is the jquery (3.1.1)/ajax request that I am using: $.ajax({ type: "POST", url: "pref.php", dataType: "text", data: { groupe_id: groupe_id, action: "getProducts" }, cache: false, error: function(html){ ...

How to bring in an interface in Angular 2

For my Meteor app using Angular 2, I am looking to create a custom data type like the one below: interface MyCustomType { index: number; value: string; } To use this custom type across multiple files, I attempted to create a separate file named "mycu ...

Is it advisable to flag non-(null|undefined)able type arguments as a type error?

Can the function throwIfMissing be modified to only flag test1 as a compiler error? function throwIfMissing<T>(x: T): T { if (x === null || x === undefined) { throw new Error('Throwing because a variable was null or undefined') ...

What is the best way to showcase Vue data of a selected element from a v-for loop in a

Here is an example of how my json data is structured. I have multiple elements being displayed in a v-for loop, and when one is clicked, I want to show specific information from that element in a modal. [{ "id": 1, "companyNa ...

The issue of continuous requests in AngularJS controllers

In my controller, I have a simple function that calculates the number of answers for each question: $scope.countAnswers = function(questionid) { AnswersQueries.getAnswers(questionid, function(answers) { var answersCount = answers.length; return ...

Having Trouble Using Fetch API with ASP.NET Core 2 Controllers that Require Authorization

I have the following code on the client side: fetch("/music/index", { headers: { "Content-Type": "application/json" } }) .then(response => { if (!response.ok) { throw response; } return response.json(); }) ...

What is the best way to conceal a global component like a navbar on specific routes?

Most of the pages on my vuejs SPA feature a top navbar component, but there are certain views like the login page where I do not want it to be displayed. My current solution involves importing the navbar and adding it to each view separately when needed. ...

The issue arises when the view fails to load while simulating a backend

Trying to test a specific element of the user interface requires a particular request to the backend with predefined data while allowing all other requests to pass through. Here's a more readable version in coffee script: describe 'select2 combo ...