Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting the prop types of a component in Vue 3 (typescript) to use them somewhere else

Vue can already infer the types of props when you annotate the props under the "props:" key of the component and that is good.

But is there an "utility type" in the vue types which can extract the type of the props from a given component?

Say I have a component defined with defineComponent and the component declaration has a props key which properly defines the names and types of the props. I want an utility type that works like this:

let someting: PropType<MyComponent> = {...};

Vue typescript types contain lots of utility types like this but I couldn't find something that does this.

like image 813
RestOfTheBothWorlds Avatar asked Sep 03 '25 05:09

RestOfTheBothWorlds


2 Answers

Figured it out; something like the following works:

import MyComponent from "./mycomponent.vue";

type MyComponentProps = InstanceType<typeof MyComponent>["$props"];

const props: MyComponentProps = { ... }
like image 116
RestOfTheBothWorlds Avatar answered Sep 04 '25 21:09

RestOfTheBothWorlds


What worked for me is this:

import {AllowedComponentProps, Component, VNodeProps} from 'vue';

type ComponentProps<C extends Component> = C extends new (...args: any) => any
  ? Omit<InstanceType<C>['$props'], keyof VNodeProps | keyof AllowedComponentProps>
  : never;

Full working example

import {AllowedComponentProps, Component, PropType, VNodeProps} from 'vue';

type ComponentProps<C extends Component> = C extends new (...args: any) => any
  ? Omit<InstanceType<C>['$props'], keyof VNodeProps | keyof AllowedComponentProps>
  : never;

type Config<C extends Component> = {
  component: C;
  props: ComponentProps<C>;
};

declare function defineConfig<C extends Component>(config: Config<C>): void;

const TestComponent = defineComponent({
  name: 'TestComponent',
  props: {
    disabled: {
      type: Boolean,
    },
    options: {
      type: Array as PropType<{key: string; value: string}[]>,
      required: true,
    },
  },
});

defineConfig({
  component: TestComponent,
  props: { // TS will throw an error because options is required but missing
    // IDE will suggest:
    //   disabled: boolean | undefined
    //   options: {key: string; value: string}[]
  },
});

Why does it need Omit?

Just InstanceType<C>['$props'] includes properties of VNodeProps and AllowedComponentProps. So, omitting their properties leaves only the actual props of the component.

Why does it need extends?

Without checking if C extends new (...args: any) => any, InstanceType will trigger TS error TS2344:

TS2344: Type 'C' does not satisfy the constraint 'abstract new (...args: any) => any'.
like image 40
Edie Lemoine Avatar answered Sep 04 '25 21:09

Edie Lemoine