在 Vue 3 (typescript) 中提取组件的 prop 类型以在其他地方使用它们

Res*_*lds 20 typescript vue.js vuejs3

当您在组件的“props:”键下注释 props 时,Vue 已经可以推断 props 的类型,这很好。

但是 vue 类型中是否有一个“实用类型”可以从给定组件中提取 props 的类型?

假设我有一个使用 DefineComponent 定义的组件,并且组件声明有一个 props 键,它正确定义了 props 的名称和类型。我想要一个像这样工作的实用程序类型:

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

Vue 打字稿类型包含许多类似的实用程序类型,但我找不到执行此操作的东西。

Res*_*lds 26

弄清楚了; 像下面这样的作品:

import MyComponent from "./mycomponent.vue";

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

const props: MyComponentProps = { ... }
Run Code Online (Sandbox Code Playgroud)

  • 在新的 Vue 3.3 组件泛型中使用这种方法,事情就会破裂: `InstanceType&lt;typeof MyComponent&lt;SomeGeneric&gt;&gt;` _Type 'typeof MyComponent&lt;SomeGeneric&gt;' 不提供与签名 'new (...args: any): any 的匹配'_ (2认同)

Edi*_*ine 10

对我有用的是:

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;
Run Code Online (Sandbox Code Playgroud)

完整的工作示例

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}[]
  },
});
Run Code Online (Sandbox Code Playgroud)

为什么需要它Omit

仅包括和InstanceType<C>['$props']的属性。因此,省略它们的属性只留下组件的实际属性。VNodePropsAllowedComponentProps

为什么需要它extends

不检查是否Cextends new (...args: any) => anyInstanceType将触发 TS 错误 TS2344:

TS2344: Type 'C' does not satisfy the constraint 'abstract new (...args: any) => any'.
Run Code Online (Sandbox Code Playgroud)