[FIXED] Unable to use defineProps with TypeScript

Issue

I have been using withDefaults and defineProps for some time now, but suddenly this has started failing and I cannot understand why!

I’ve a basic SFC like:

<script
  setup
  lang = "ts">
  const props = withDefaults(defineProps<{
    foo : RegExp
  }>(), {
    foo: /./
  })
</script>
<template>
  <!-- rest of the stuff -->
</template>

The build fails with the error:

error TS2322: Type 'RegExp' is not assignable to type '(props: Readonly<{ foo?: RegExp | undefined; }>) => RegExp'.
  Type 'RegExp' provides no match for the signature '(props: Readonly<{ foo?: RegExp | undefined; }>): RegExp'.

14     foo: /./,
       ~~~

  src/App.vue:11:5
    11     foo?: RegExp;
           ~~~
    The expected type comes from property 'foo' which is declared here on type 'InferDefaults<Readonly<{ foo?: RegExp | undefined; }>>'


Found 1 error in src/App.vue:14

I’ve setup a minimal reproduction in StackBlitz: https://stackblitz.com/edit/vitejs-vite-du7xik?file=src%2FApp.vue

I’m having a few more issues suddenly related to Typings, with my otherwise working application, but one at a time. Any guidance would help!

EDIT:

The problem only happens when running a production build (as vue-tsc is called only then). On StackBlitz, this would mean running turbo build in the terminal. Apart from that, at least when using IntelliJ, I was also able to see the error in IDE.

Solution

The error means that foo default value was provided as is, while factory function is expected.

It should be:

foo: () => /./,

It’s a mistake to specify prop default value directly because it will be shared across multiple component instances, they may affect each other through it. This specifically applies to regex objects which can be stateful.

Answered By – Estus Flask

Answer Checked By – Marilyn (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published