在Vue中,我们具有以下类型:
Vue.$refs: {
[key: string]: Vue | Element | Vue[] | Element[];
}
我有一个第三方库(vuelidate),它为所有Vue添加了一个$v
属性。它没有定义类型,所以我自己做。
declare module 'vue/types/vue' {
interface Vue {
$v: any
}
interface Element {
$v: any
}
}
当我尝试在$ refs上使用$v
时,打字稿抱怨:
this.$refs.form.$v
结果
Property '$v' does not exist on type 'Vue[]'.
这对我来说很有意义。但是,没有意义的是如何向Vue[]
和Element[]
添加属性,以便编译此代码。
我已经遍历了文档“ Stack Overflow”,您为它起了名字,但我找不到解决方案。如何将类型添加到特定数组?
我了解为什么这行不通:
interface Vue[] {
$v: any
}
但是我不知道该如何解决。
答案 0 :(得分:1)
强制转换有效,但是我很感谢您希望声明类型,因此您不必每次都强制转换。 Vue[]
实际上是Array<Vue>
的缩写,Array
是内置通用接口Array
的参数化。您可以将属性添加到Vue[]
,但是随后将在所有类型的数组上声明它们,而不仅仅是// Wrap with `declare global { ... }` if the file is an ES6 module
interface Array<T> {
$v: T extends Vue | Element ? any : unknown;
}
。您可以使用条件类型来缓解这种情况,如下所示:
$v
但实际上,您不希望每个Vue[]
上都有Vue.$refs
,而只希望Vue.$refs
上。不幸的是,考虑到声明vue
的方式,我不认为有任何方法可以通过扩充来进行此更改。您必须在项目中添加export interface Vue {
// ...
readonly $refs: { [key: string]: (Vue | Element | Vue[] | Element[]) & {$v: any} };
// ...
}
软件包的修改版本,并将声明更改为:
vuelidate
显然,此更改不适合向上游发送。但是您可以发送PR来添加一个钩子,以便其他软件包(例如// In vue/types/vue.d.ts:
export interface RefExtra {}
export interface Vue {
// ...
readonly $refs: { [key: string]: (Vue | Element | Vue[] | Element[]) & RefExtra };
// ...
}
// In vuelidate typings (or your project for now):
declare module 'vue/types/vue' {
interface RefExtra {
$v: any
}
}
)可以增强:
git add <folder>/*