I'm using a stack of technologies, so I'm finding it hard to find the source of the problem.
Here is the Stack:
- Vue 3
- TypeScript
- Vite
- VSCode / Volar
- unplugin-vue-macros (https://github.com/sxzz/vue-macros)
- unplugin-vue-components (https://github.com/antfu/unplugin-vue-components)
I have a component (MetadataTemplate.vue) which exports these props:
interface Props {
  link: Link
  type: 'link' | 'collection'
  showSuccess?: Function
  refresh?: Function
  displayButtons?: boolean
}
const props = withDefaults(defineProps<Props>(), {
  type: 'link',
  refresh: () => {}
})
Notice that type is a required property. However, this code throws a TypeScript error:
<MetadataTemplate
  :type="pageType"
  :link="link"
/>
pageType is of type 'link' | 'collection'. However, TypeScript (Volar) reports:
Type 'string' is not assignable to type '"collection" | "link" | undefined'.ts(2322)
MetadataTemplate.vue(33, 3): The expected type comes from property 'type' which is declared here on type 'Partial<{ type: "collection" | "link"; refresh: Function; }> & Omit<Readonly<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, { ...; }>>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, DefaultKeys<...>> & Record<...>'
In other words, it's exporting the props as a Partial. Is this something that Vue / TypeScript always does? Or something that Volar expects? I don't know what could be translating a set of props to Partial props.
 
                        
Okay, I think I figured it out.
As @zenly said, the Partial wasn't the cause of the error. The error was that Volar / TypeScript was inferring the type of
pageTypewithin VSCode as'link' | 'collection'but it wasn't actually of that type, because Vue's language services weren't correctly inferring the type ofpageTypeby the time it was bound to the template (and was inferring that it was just a string).I fixed it by explicitly defining
pageTypeas that type.