Vue3 typescript script setup获取范型组件的ref

发布时间 2023-10-20 18:06:39作者: maurrinho

原博客地址: https://juejin.cn/post/7247433208437850169?from=search-suggest

在typescript下,如果想获取带类型的组件模板引用,官方文档中说明了方式: https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-template-refs

const modal = ref<InstanceType<typeof MyModal> | null>(null)

但如果这个MyModal是一个范型组件:

<script setup lang="ts" generic="T extends string | number, U extends Item">

上面获取ref的方法就会报错Type '<T extends XXX | XXX | XXX>(__VLS_props: { ...; } & ... 2 more ... & ComponentCustomProps, __VLS_ctx?: Pick<...> | undefined, __VLS_setup?: Promise<...>) => VNode<...> & { ...; }' does not satisfy the constraint 'abstract new (...args: any) => any'.

那么这种情况下该如何获取这个ref?开头的博客给出了答案:

  1. 在项目中定义一个type-function.d.ts
type GenericComponentExports<D extends (...p: any[]) => any> = import('vue').ComponentPublicInstance &
  Parameters<NonNullable<NonNullable<ReturnType<D>['__ctx']>['expose']>>[0];
  1. 在需要获取组件ref的地方使用GenericComponentExports
const dialogRef = ref<GenericComponentExports<typeof TestComponent>>();

下面解释一下代码
type GenericComponentExports<D extends (...p: any[]) => any> 声明一个范型类型,它接受一个范型参数D。D是一个函数类型,可以接受任意数量的参数(...p: any[]),并且返回任意类型。实际上,D代表了组件的构造函数

import('vue').ComponentPublicInstance:这部分导入了 Vue.js 的 ComponentPublicInstance 类型,它代表了 Vue 3 组件的公共实例。

ReturnType<D>用来获取函数类型D的返回类型

ReturnType<D>['__ctx']:获取返回类型的 __ctx 属性

NonNullable<ReturnType<D>['__ctx']>: 移除了可能为 null 或 undefined 的类型

Parameters<NonNullable<NonNullable<ReturnType<D>['__ctx']>['expose']>>[0]: 最后,Parameters 是一个工具类型,它用于获取函数类型的参数类型,而 [0] 则表示获取参数类型数组的第一个元素