Why are the Vue props wrapped in `Partial<>`?

439 Views Asked by At

I'm using a stack of technologies, so I'm finding it hard to find the source of the problem.

Here is the Stack:

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.

1

There are 1 best solutions below

0
On

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 pageType within VSCode as 'link' | 'collection' but it wasn't actually of that type, because Vue's language services weren't correctly inferring the type of pageType by the time it was bound to the template (and was inferring that it was just a string).

I fixed it by explicitly defining pageType as that type.