Utilizing the validator in Vue with the setup script, TypeScript, and the composition API

While working on some code from a tutorial, I came across the challenge of implementing a validator in a similar fashion to the example provided. My task involves utilizing the script setup, typescript, and the composition API.

props: {
    image: {
      type: String,
      default: require("@/assets/default-poster.png"),
      validator: propValue => {
        const hasImagesDir = propValue.indexOf("@/assets/") > -1;
        const listOfAvailableExt = [".jpeg", ".jpg", ".png"];
        const isValidExt = listOfAvailableExt.some(ext =>
          propValue.endsWith(ext)
        );
        return hasImagesDir && isValidExt;
      }
    }
  }

Although I understand how to define the type and set a default value, I'm struggling to incorporate a validator into the mix. Is there a specific function that can be used to validate different properties?

interface Props {
  image: string
}

const props = withDefaults(defineProps<Props>(), {
  image: require("@/assets/default-poster.png")
});

Answer №1

When using <script setup>, only the argument within the function of defineProps() is able to utilize the validator feature, according to Vue 3.2.31 specifications. This function argument must follow the same data type as the props option:

defineProps({
  image: {
    type: String,
    default: require("@/assets/default-poster.png"),
    validator: (propValue: string) => {
      const hasImagesDir = propValue.indexOf("@/assets/") > -1;
      const listOfAvailableExt = [".jpeg", ".jpg", ".png"];
      const isValidExt = listOfAvailableExt.some(ext =>
        propValue.endsWith(ext)
      );
      return hasImagesDir && isValidExt;
    }
  }
})

It's important to note that you cannot mix the type-only props declaration with the function argument of defineProps(). Any other props would need to be converted into the option form as well.

Alternatively, you have the option to create your own prop validation logic:

<script setup lang="ts">
interface Props {
  image: string
}

const props = withDefaults(defineProps<Props>(), {
  image: require("@/assets/default-poster.png")
});

if (import.meta.env.DEV /* process.env.NODE_ENV === 'development' */) {
  const isValidImage = (propValue: string) => {
    const hasImagesDir = propValue.indexOf("@/assets/") > -1;
    const listOfAvailableExt = [".jpeg", ".jpg", ".png"];
    const isValidExt = listOfAvailableExt.some(ext =>
      propValue.endsWith(ext)
    );
    return hasImagesDir && isValidExt;
  }

  if (!isValidImage(props.image)) {
    console.warn(`invalid image: ${props.image}`)
  }
}
</script>

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

``Is it possible to iterate through a collection of objects using a loop?

I am facing an issue with updating a global array that contains objects, where each object includes another array. My goal is to update the main array with values from the arrays within the objects following a specific logic! generalArray = [{name:String, ...

What is the best way to incorporate a @types module into a TypeScript file that is not already a module?

Setting the Stage: In the process of shifting a hefty ~3,000 line inline <script> from a web-page to a TypeScript file (PageScripts.ts) to be utilized by the page through <script src="PageScripts.js" defer></script>. This script entails ...

Error encountered in Angular2: Attempted to access property 'compilerOptions' which is undefined

I encountered a TypeError: Unable to access the 'compilerOptions' property of undefined Below is the snippet of my compilerOptions code: { "compilerOptions": { "target": "ES5", "module": "commonjs", "emitDecoratorMetadata": tr ...

Error: The function list.forEach does not exist within service.buildList [as project]

Today, I've been grappling with a challenging issue. As someone new to Typescript and Angular, I'm attempting to make a call to my backend API. However, when trying to populate an array for display, I keep encountering an error that says rawRegis ...

Updating the value of an Angular select on change is not being reflected

If the select element is changed, the value should be set to something different from what was selected. There's a feature in place that only allows 4 item types to be selected at a time; if more than 4 are chosen, the value reverts back to its origin ...

Tips for importing a .ts file into another .ts file within an Angular 5 application

I have a bunch of utility methods stored in a file called utils.ts that I want to reuse across multiple components. I'm not sure if it's even possible, and if it is, where should I place the import statement and what would be the correct syntax. ...

gather and handle data from the shared interface between different parts

I have two different paths. One is for products and the other is for products-cart. I want to use a shared ts file for both to store the product and cart information in an array. However, I am encountering an issue. I am unable to make any changes or trans ...

Error in Typescript occurrence when combining multiple optional types

This code snippet illustrates a common error: interface Block { id: string; } interface TitleBlock extends Block { data: { text: "hi", icon: "hi-icon" } } interface SubtitleBlock extends Block { data: { text: &qu ...

Discover a Simple Trick to Enhance tsc Output: Unveil the Art of

When I work on a TypeScript project, I typically use the watch mode of the compiler: tsc --watch However, one issue I face is that it's challenging to identify errors in the output since they are displayed as plain text: Sometimes I don't even ...

Discovering the best method to retrieve user details (email address) following a successful login across all pages or components within Angular

Discovering the world of Angular and TypeScript is quite exciting. In my Angular project, I have 8 pages that include a login and registration page. I'm facing an issue where I need to access the user's email data on every page/component but the ...

The NGRX state spread operator requires the Type to include a '[Symbol.iterator]()' function

Utilizing NGRX Entity adapter for state initialization has been encountering an issue, specifically with the getInitialState method. export const initialState = adapter.getInitialState({ eventsError: null, eventsLoading: false }); ex ...

Function arity-based type guard

Consider a scenario where there is a function with multiple optional parameters. Why does the function's arity not have a type guard based on the arguments keyword and what are some solutions that do not require altering the implementation or resorti ...

Testing React components with React Testing Library and Effector (state manager) made easy

I am currently utilizing effector along with React Testing Library (RTL). While going through the RTL documentation, I came across an interesting article regarding the usage of customerRender, where we provide AllTheProviders as a wrapper for the render fu ...

Encountered a Vue.js Vuex error: "Unable to dispatch function in context."

I have implemented a stopwatch function that can run the stopwatch as shown below : Stopwatch.vue <script> export default { data() { return { time: "00:00.000", timeBegan: null, timeStopped: null, stoppedDurat ...

Is the ng-selector in Angular2 not sorting items alphabetically as expected?

This code snippet demonstrates the use of ng-selector in an .html file <ng-selector name="company" [(ngModel)]="company_selected" [formControl]="loanApplyForm.controls['company']" ...

Utilize focusout and onclick events on multiple components at the same time

Currently, I am in the process of coding an Autocomplete feature from scratch in Vue, but I am encountering a challenge when it comes to selecting an option from the dropdown menu. I have set it up so that the dropdown is shown when the input is clicked ...

Challenge: Visual Studio 2015 MVC6 and Angular 2 compilation issue - Promise name not found

Initially, I've made sure to review the following sources: Issue 7052 in Angular's GitHub Issue 4902 in Angular's GitHub Typescript: Cannot find 'Promise' using ECMAScript 6 How to utilize ES6 Promises with Typescript? Visual ...

Tips for enhancing the TypeScript definition of Material UI 3 theme by integrating the Material UI pickers theme

Trying to enhance the Material-UI theme with the Typescript typings of Material-UI-Pickers for the latest versions listed here: "@material-ui/core": "^3.9.2", "material-ui-pickers": "^2.2.1", A note on the bottom of the Material UI picker page mentions t ...

Tips for configuring TypeScript in a monorepo to successfully compile private packages

I have configured a monorepo using turborepo that includes Nestjs for the backend and Nextjs for the frontend. To reuse prisma definitions, I separated them into their own package with its own tsconfig. In the index file of my database package where prism ...

Attempting to utilize a namespace-style import for calling or constructing purposes will result in a runtime failure

Using TypeScript 2.7.2 and VSCode version 1.21 with @types/express, I encountered an issue where in certain cases VSCode would report errors like: A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Interestingly ...