Utilizing Vue 3 props validation in conjunction with the power of Typescript

Looking to customize a Link component using Nuxt, Typescript, and the composition-api. The prop target can accept specific values as outlined below. I'm curious if using a custom validator function to check prop types at runtime adds value when compared to the static nature of Typescript types?

Is there any benefit in combining both approaches?

import { defineComponent } from '@nuxtjs/composition-api';

export default defineComponent({
  name: 'Link',
  props: {
    target: {
      type: String as () => '_self' | '_blank' | '_parent' | '_top',
      default: '_self',
      validator: (value: string) => {
        return ['_self', '_blank', '_parent', '_top'].includes(value);
      },
    },
  },
});

Answer №1

It is true that TypeScript types are checked only during the build-time, while validator()s serve as runtime guards.

The relationship between Vue and TypeScript can be described as complex. Those who have experience with React may recall how a TypeScript error would be thrown for

<Link target="some_invalid_value"/>
without additional configuration. In Vue, encountering such an error (such as obtaining TS prop validation in the template) could be considered somewhat "new."

Using TypeScript can offer a more user-friendly developer experience if you manage to set up enhancing extensions successfully. However, it's important to remember:

  • TypeScript prop validation remains relatively experimental and unstable
  • These extensions will only function within VSCode. Running npm run build might not display errors unless a tool like https://github.com/vuejs/vetur/tree/master/vti is utilized - this Vetur addon reports the same errors visible in VSCode but does so in the terminal during CI, potentially halting a build upon detecting errors.

If you anticipate that others will use your Link component across various projects - especially in scenarios lacking TypeScript or employing Vue directly in .html files sans webpack - consider that they won't benefit from your TypeScript types but could still make use of validator().

Could you test incorporating your Link component into another component, then passing

<Link target="some_invalid_value"/>
to see if TypeScript errors occur? If not, additional configuration with these extensions (VSCode specific) may be necessary:


Here are some extra suggestions:

I've observed that the type assertion (as) you're using is non-standard. The Vue documentation suggests utilizing as PropType, as outlined in https://v3.vuejs.org/guide/typescript-support.html#annotating-props

Avoid using single-word component names. This guideline holds great importance as it ranks as "Essential" in the styleguide: https://v3.vuejs.org/style-guide/#multi-word-component-names-essential

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

I Tried Adding Up All the Numbers, but It Doesn't Seem to Work for Every Dynamic Total Field

In my project, I am utilizing Laravel 5.7 and VueJs 2.5.*. The issue I am facing is that when I input values, the Total field calculates correctly. However, when I dynamically add rows for items, the calculation only works for the first row and not for the ...

You can't observe the behavior of simulated functions in a class with a manually created mock

Kindly note that I have set up a comprehensive Github repository where you can download and explore the content yourself here I am currently working on mocking a non-default exported class within a module using a manual mock placed in the folder __mocks__ ...

Encountering "Cannot write file" errors in VSCode after adding tsconfig exclude?

When I insert the exclude block into my tsconfig.json file like this: "exclude": ["angular-package-format-workspace"] I encounter the following errors in VSCode. These errors disappear once I remove the exclude block (However, the intended exclusion fu ...

Caution: Using Blade template data with Vue may trigger a warning

I encountered an error related to Vue [Vue warn]: Property or method "product" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializi ...

Discovering the Depths of Data Structures in Vue (Arrays and Objects)

I have an object variable where I need to monitor certain keys This is my object: user{ name, address, city, dob } Specifically, I want to monitor the 'address' and 'city' properties This is ho ...

Displaying varying values of an object using TypeScript's console log trick

While using Angular version 8 with RJXS library, I encountered a peculiar issue when attempting to log an object variable: Object { carName: "Sorbonne", age: "20", type: "C1" } ​ carName: "BB" ​ age: "23&quo ...

What is the process of programmatically sorting a column in a Material UI DataGrid?

Hey there! I'm currently working on a DataGrid that has a column with a custom header, specifically a Select option. My goal is to have the column sorted in descending order every time a user selects an option from the dropdown menu. renderHeader: (pa ...

How about: "Interactive web form featuring customizable options to determine which fields are shown?"

How can I design a dynamic web form that changes based on selected options? This form will include standard fields as well as customized fields depending on the user's previous selections. There are approximately 120 different combinations of forms p ...

When attempting to assign a 'string' type to the @Input property, I am receiving an error stating that it is not assignable to the 'PostCard Layout' type

Encountering an issue The error message 'Type 'string' is not assignable to type 'PostCard Layout'' is being displayed A parent component named page-blog.component.html is responsible for defining the class styles and passi ...

Is there a way to easily copy the content within the <code> tag to the clipboard?

I've attempted to use the following code, but unfortunately, it's not functioning properly. Is there a way for me to copy the contents inside the <code> tag to my clipboard? <pre id="myCode"> <code> console.lo ...

Including a hyperlink in VUE Bootstrap for seamless user navigation

Why does this always drive me crazy? I'm determined to include an external link () and an image(enter image description here) on my portfolio page within the title of the project. main.js { id: 18, url: 'single-portfolio. ...

TS2304: 'Omit' is a mysterious being that cannot be located

Encountered an issue while compiling my Angular project. This is a project that has remained unchanged for some time and is built daily by Jenkins. However, today it started failing and I'm struggling to determine the cause. ERROR in [at-loader] ./no ...

Tips for making a property non-nullable in Typescript

The Node built-in IncomingMessage type from DefinitelyTyped's definition (used as req in the (req, res, next) arguments) has specified that url can be nullable. This excerpt shows part of the definition: // @types/node/index.d.ts declare module "http ...

Is there a way to prompt TypeScript to report an error when a mapped key is missing?

Here is my current code snippet: type TransferType = 'INTERNAL' | 'WITHDRAWAL' | 'DEPOSIT' type TransferEvents = Record<TransferType, Record<string, TypeFoo | TypeBar>> export interface EventsTooltip extends Tran ...

Enhance the TypeScript interface by dynamically appending new fields with specific naming conventions

My interface is structured like this: interface ProjectCostData { purchasePrice: number; propertyValue: number; recentlyDamaged: boolean; } Now I am looking to dynamically create a new interface based on the one above: interface ProjectCostDataWithS ...

Fixed header in a div, allowing content to scroll when hovering over the header

How can I ensure that the header remains fixed at the top while allowing the content to scroll when hovered over? The current issue is that when a user hovers over the header and tries to scroll, the content does not move. body { margin: 0; ...

The Unhandled Promise Rejection Warning in mocha and ts-node is due to a TypeError that arises when attempting to convert undefined or null values

I've been encountering issues while setting up ts-node with mocha, as the test script consistently fails. I attempted to run the following commands: mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'src/**/*.spec.{ ...

Tips for typing a narrow JSX.Element

Is there a way to create a variable in React that can be either a component or a string? Like this: function MyComponent(): JSX.Element { let icon: JSX.Element | string = "/example.png"; return <div>{typeof icon === "JSX.Element" ? icon : <i ...

What impact does setting 'pathmatch: full' in Angular have on the application?

When the 'pathmatch' is set to 'full' and I try to delete it, the app no longer loads or runs properly. import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { H ...

The IDE is able to detect interface extensions in d.ts files, but TypeScript is not recognizing them

When developing in ES6 style module inclusion within WebStorm, I encountered an issue with my Express app and a custom d.ts file. The d.ts file contains middleware that alters objects, and the structure looks like this: declare module Express { export ...