vch*_*vch 7 typescript vue.js vuejs3 vue-script-setup
我有这个组件 A 和一个公开的方法send
A.vue:
<script setup lang="ts">
function send(data: string) {
console.log(data)
}
defineExpose({ send })
</script>
Run Code Online (Sandbox Code Playgroud)
以及导入该组件的组件B
B.vue
<template>
<ComponentA ref="a" />
</template>
<script setup lang="ts">
import ComponentA from '@/component-a.vue'
const a = ref()
onMounted(() => a.value.send(22)) // should be a type error
</script>
Run Code Online (Sandbox Code Playgroud)
如何键入导入的组件,以便当我通过 refs 调用其方法时,它会检查公开的方法名称和传递参数的类型?
我尝试了谷歌搜索:ComponentPublicInstance<typeof ComponentA>但它似乎没有检查方法。
编辑:
这是 shims-vue.d.ts (由 vue-cli 生成):
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
Run Code Online (Sandbox Code Playgroud)
编辑:
这是复制品。
如您所见,在 HelloWorld.vue 中,a引用的是 ComponentA 的实例。我尝试用 键入它const a = ref<InstanceType <typeof ComponentA>>(),但没有运气,它被键入为any
ton*_*y19 14
的实例类型ref()是 a Ref<T>,其中T(默认为any)指定其属性的类型.value。
您没有提供泛型类型,并且不存在用于推断类型的初始值设定项参数,因此 TypeScript 假定T为any,因此a.value类型为any。因此,a.value.send也是类型any,它不会提供任何类型安全(正如您所观察到的)。
在这种情况下,您应该声明 with 的泛型类型ref:
const a = ref<InstanceType<typeof ComponentA>>()
a.value?.send(22) // error: Argument of type 'number' is not assignable to parameter of type 'string'.
Run Code Online (Sandbox Code Playgroud)
就 TypeScript 而言, ComponentA 的类型是DefineComponent<{}, {}, any>,因为您shims-vue.d.ts如此声明它。(我想你也会比 更幸运import ComponentA。import { ComponentA })TypeScript 不理解如何解析 Vue SFC 文件,因此 TypeScript 被迫信任你的.d.ts文件。
在VSCode 等使用 Volar 或 Vetur 等扩展的 IDE中,您可能会得到比单独使用 TypeScript 更具体的类型检查;这是因为 Vetur 和 Volar 足够聪明,可以读取 Vue SFC 文件并适当地键入它们,而忽略全局.d.tsshim。
如果您想要在不使用 IDE 的情况下进行更智能的 TypeScript 检查,那么就像Vue Typescript 概述部分一样,您需要使用vue-tsc,它是一个与 Volar 共享代码但理解 SFC 文件的 TypeScript 包装器。您还可以用来vue-tsc生成一个更具体的.d.ts文件,该文件将写出 TypeScript 验证 SFC 所需的上下文,而无需使用 Vue 感知包装器。
| 归档时间: |
|
| 查看次数: |
9725 次 |
| 最近记录: |