1
votes

I'm trying to extend a 3rd party Vue component (from PrimeVue) and add additional props, but I'd like to keep the typings of the original component and also union them with my additional props.

For example, using the 3rd party Button component below which has typings that enforce "label" must be a string, my IDE (VSCode + Vetur) will mark it as an error if I attempt to pass a numeric.

If I were to extend the Button class into my own component, BaseButton, using the common pattern below, I will be able to pass a numeric or any other type to the label prop without the IDE complaining. Besides maintaining the typings of the original Button component, I want to union it with my additional props, e.g. myProp: string below.

<template>
  <Button v-bind="$attrs" :label="myComputedLabel">
    <template v-for="(_, slot) of $slots" v-slot:[slot]="scope">
      <slot :name="slot" v-bind="scope"/>
    </template>
  </Button>
</template>

<script>
  export default defineComponent({
  name: 'BaseButton',
  props: {
    myProp: {
      type: String
    }
  },
  setup(props) {
    const myComputedLabel = computed(() => {
      return `Hello ${props.myProp}`;
    });
  }
 })
</script>

In my case, the 3rd party component is written in Vue with vanilla JS but has an external Button.d.ts typings file. I'm not sure if that matters.

1
Would you mind giving an example? The library does not export the interface: github.com/primefaces/primevue/blob/master/src/components/… It exports a class Button, but I'm not sure how to merge the $props field without redeclaring all the props myself. - nogridbag

1 Answers

0
votes

you can read it from the component's setup option, the props is the first argument of setup

type MyButtonProp = Parameters<NonNullable<typeof Button.setup>>[0]

Simply, here's a Generic Type

type ComponentProps<T extends { setup?: any }> = Parameters<NonNullable<T['setup']>>[0]

usage

type MyButtonProp = ComponentProps<typeof Button>