Skip to content

App fails at runtime even though TS and Volar are happy with generic defineComponent Props type #7832

Closed as not planned
@rdhelms

Description

@rdhelms

Vue version

3.2.47

Link to minimal reproduction

https://sfc.vuejs.org/#eNqNUsuO1DAQ/JXGl9mVJrG4RmEkxAUuCGkRJ1+8SWfiVWIbt7NLFOXfaecxWRYhccijbXdXuaom8dH7/HlAUYiSqmB8hE7b6wclIilxUVZF03sXInxyvYcmuB5OuUxFajspC5Ae/LUcqrHRQxdhSmsAFR9zFm2kYl+CZdB5Leb04VcpV+yEZ8uIve90RK4AyndZBj9cpwNPCwGr2I1ArXsh0BYwBBegxYBgGiDX47fgPBgC6yJ4TYQ1ZNkx6Q6f0cKLia0btjuRx8o0o7FXCIPl6yJ4HkL3t8blWJGmZ2mHxfnsXNCjEvKY/H30+LAqqG29UdZMrNXej6CbiGFhlIB2pmd4ZBo7bKNNRytqKV+pIM5iNSHrtc+fyFm2a9FTbRvs1U1hJdiYVCvRxuipkJKaKrn1RLkLV8l/+QaZI/XZY2A1MfBgJTZDZobcPf5nNAC2aEzJd2MxdSx2w7wl5XVEpISHQ+rYIiQFCCILB7VDsieWAn8OhkXTf3rBABXrqaNxnJC/4vYGvpxuAhdAMSS8+XI3zfcsD9P46lbQIz3/G8HURkfONIdwB0hjzmnly6lO/DiptwC17y8HoelgB/NcSt586/f8GwO4PA8=

Steps to reproduce

App fails at runtime even though TypeScript and Volar are happy with defineComponent Props type.

App.vue

<script lang="ts">
  import Comp from './Comp.vue'
  
  export default {
    components: {
      Comp,
    }
  }
</script>

<template>
  <!-- Volar correctly shows an error here if someProp is not passed -->
  <!-- (even without Comp specifying runtime props) -->
  <Comp :some-prop="Hooray"/>
  <!-- TypeScript and Volar are happy after passing someProp, but runtime fails -->
</template>

Comp.vue

<script lang="ts">
  import { defineComponent } from 'vue'
  
  // Specifying the Props type doesn't require a runtime props declaration
  export default defineComponent<{ someProp: string }>({})   // No type error here
</script>

<template>
  <!-- Volar types someProp as a string here, as I'd expect -->
  <h1>someProp: {{ someProp }}</h1>
</template>

What is expected?

Initially from reading the Vue docs, I expected to see a type error about not specifying the runtime props in the object passed to defineComponent along the lines of "Type undefined not assignable to (whatever my prop types were)".

BUT when I realized that TypeScript was happy AND that Volar was correctly seeing the prop type in the template AND that Volar was seeing the prop as required in the parent component's template...I started to think that this would "just work" even in runtime.

What is actually happening?

Sadly the app still failed at runtime with the error

Property "someProp" was accessed during render but is not defined on instance.
 at <Compsome-prop=undefined>
 at <Repl>

But then I thought...why does that need to fail? Ultimately I don't care about the runtime validation if TypeScript and Volar are already validating the props as I'm writing the code. Now runtime validation of component props feels like trying to do runtime validation of function params - we don't really need it.

System Info

System:
    OS: macOS 12.6.3
    CPU: (10) arm64 Apple M1 Pro
    Memory: 204.77 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
    npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
  Browsers:
    Chrome: 110.0.5481.177
    Firefox: 101.0
    Safari: 16.3
  npmPackages:
    vue: ^3.2.45 => 3.2.47

Any additional comments?

As a side note, part of my motivation for trying the generic Props type parameter in the first place is that I hate the idea of using JS prototypes just to accomplish all I really care about, which is type checking.

I would ALSO love if defineComponent's "Emits" generic type parameter could be second in the list of type parameters instead of way later...because if I'm able to specify both the props and the emits types right there in defineComponents (and if I can opt out of the runtime validation for both), then 💯 🎉

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions