language-tools: Calling prop fields in the template (like `props.foo`) doesn't work with `withDefaults`

This is issue originated from this vue/core discussion. Apparently it’s not a vue/core error.

This is the error:

gen-err

Reproducible:

<script setup lang="ts" generic="T">
const props = withDefaults(defineProps<{
	value?: T | null;
	list: T[];
}>(), {
	value: null,
});
</script>

<template>
	<select>
		<option v-for="item of props.list">

		</option>
	</select>
</template>

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 17 (8 by maintainers)

Most upvoted comments

This works fine, I do not think it is in Vue core.

import { defineComponent, h, ref } from "vue";

export interface ListItem {
  id: string;
  title: string;
}

const Comp = defineComponent(
  // TODO: babel plugin to auto infer runtime props options from type
  // similar to defineProps<{...}>()
  <T extends ListItem>(props: { msg: T; list: T[] }) => {
    // use Composition API here like in <script setup>
    const count = ref(0);

    return () => h("div", props.msg.title);
  }
);
image

@rodrigocfd I’m working on this now, but I’m not sure if I can fix it 😂

@xiaoxiangmoe you’re still changing the type of props by returning them on the setup, the clean $props are located _ctx.$props and I would recommend using them instead.

image
<script setup lang="ts" generic="T">
const props = withDefaults(defineProps<{
	value?: T | null;
	list: T[];
}>(), {
	value: null,
});
</script>

<template>
	<select>
		<option v-for="item of list">

		</option>
      {{ $props.list }}
    </select>
</template>

While testing this I’ve noticed Volar does not resolve the type correctly when using instance type, altho it works in the <template>?

eg:

import  MyComp from './MyComp.vue'

// this is errored
const el = ref<null | InstanceType<typeof MyComp>>(null)
image

fixed code is

const el = ref<null | InstanceType<typeof MyComp<any>>>(null)

I was using v1.8.15, after updating to v1.8.18 (latest) it’s working fine. Sorry, my bad.

Thanks for the help.