如何在Vue 3中使用`defineComponent()`之外的方式声明Vue实例?

11

如您所知,从Vue 3开始,组件可以用TypeScript编写:

/// modal.vue

<template>
  <div class="modal"></div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "Modal",
  props: {
    foo: String,
    bar: String
  },
  mounted() {
    this.$props.foo // how to type `this` out of this context?
  }
});
</script>

我的问题是如何在defineComponent函数之外输入vue实例?

/// another ts file.
let modal:???; // what the `???` should be?

modal.$props.foo // infer `$props.foo` correctly
2个回答

10
使用TypeScript内置的InstanceType实用程序来提取其实例类型。
import Modal from './modal.vue'

type ModalInstance = InstanceType<typeof Modal>

type Foo = ModalInstance['$props']['foo']

enter image description here

另一种使用实用程序类型的方法:

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

export type ExtractComponentProps<TComponent> =
  TComponent extends new () => {
    $props: infer P;
  }
    ? Omit<P, keyof VNodeProps | keyof AllowedComponentProps>
    : never;
  
const TestComponent = defineComponent({
  props: {
    disabled: {
      type: Boolean,
    },
  },
});
  
type Props = ExtractComponentProps<typeof TestComponent>

// type Props = {
//   disabled?: boolean | undefined;
// }

9
我本来想给出一个“简单”的答案,即使用 ReturnType<typeof defineComponent>,但这并没有包含任何类型信息。在尝试将 ReturnType 与泛型方法一起使用时,我发现了一个类似于stackoverflow的兔子洞
然而,在查看后,vue有一个导出类型叫做ComponentPublicInstance,可以相当容易地使用。此外,ComponentPublicInstance 还有许多不同的泛型参数。
import { ComponentPublicInstance } from 'vue';

let instance: ComponentPublicInstance<{ prop: string }, { value: string }>;

适用于组件,但对于没有<script>标签的组件(例如仅有<template>的组件),会抛出类型错误。 - Letik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接