如何在 Vue Router v4 中为自定义元字段声明 TypeScript 类型接口?
How to declare TypeScript type interface for custom meta fields in Vue Router v4?
使用 Vue Router 版本 4,目前 in beta.11 in vue-router-next repo, there is a documentation page 关于 如何使用 TypeScript 定义元字段自定义类型接口 .
declare module 'vue-router' {
interface RouteMeta {
// is optional
isAdmin?: boolean
// must be declared by every route
requiresAuth: boolean
}
}
沿着 Vue shim 模块声明放置。我的看起来像:
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
export default component;
}
declare module 'vue-router' {
interface RouteMeta {
isPublic?: boolean;
}
}
但是,这不起作用。相反,这种定义接口的方式似乎覆盖了包附带的接口,或者更确切地说,声明 'vue-router' 模块似乎可以做到这一点。
定义自定义元字段类型的正确方法是什么?
他们的文档是错误的,或者充其量是不完整的。
一个 Module Augmentation uses the same syntax as an Ambient Module 声明,仅当它位于模块文件本身时才被视为扩充。根据 ECMAScript 规范,模块被定义为包含一个或多个顶级 import
或 export
语句的文件。
非模块文件中的代码段与您注意到的完全相同。它取代了 'vue-router'
包的任何其他类型,而不是增加它们。但我们想增加该包的类型,而不是替换它们。
但是,作为声明而不是扩充的 declare module
语句必须位于文件中,反之,也不是模块。也就是说,在包含任何顶级 import
或 export
语句的文件 not 中。
要解决此问题,请将 declare module 'vue-router' {...}
移动到一个单独的文件(例如,augmentations.d.ts
),并通过以 export {}
.[=25= 开头使该文件成为一个模块]
// augmenations.d.ts
// Ensure this file is parsed as a module regardless of dependencies.
export {}
declare module 'vue-router' {
interface RouteMeta {
// is optional
isAdmin?: boolean
// must be declared by every route
requiresAuth: boolean
}
}
现在回过头来看看问题的原代码
// shims-vue.d.ts
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
export default component;
}
declare module 'vue-router' {
interface RouteMeta {
isPublic?: boolean;
}
}
两个 declare module
语句不能存在于同一个文件中,因为其中一个试图声明一个模块,'*.vue'
,另一个试图扩充一个。因此,我们将 declare module '*.vue' {...}
保留在原处,因为它按预期运行。
使用 Vue Router 版本 4,目前 in beta.11 in vue-router-next repo, there is a documentation page 关于 如何使用 TypeScript 定义元字段自定义类型接口 .
declare module 'vue-router' {
interface RouteMeta {
// is optional
isAdmin?: boolean
// must be declared by every route
requiresAuth: boolean
}
}
沿着 Vue shim 模块声明放置。我的看起来像:
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
export default component;
}
declare module 'vue-router' {
interface RouteMeta {
isPublic?: boolean;
}
}
但是,这不起作用。相反,这种定义接口的方式似乎覆盖了包附带的接口,或者更确切地说,声明 'vue-router' 模块似乎可以做到这一点。
定义自定义元字段类型的正确方法是什么?
他们的文档是错误的,或者充其量是不完整的。
一个 Module Augmentation uses the same syntax as an Ambient Module 声明,仅当它位于模块文件本身时才被视为扩充。根据 ECMAScript 规范,模块被定义为包含一个或多个顶级 import
或 export
语句的文件。
非模块文件中的代码段与您注意到的完全相同。它取代了 'vue-router'
包的任何其他类型,而不是增加它们。但我们想增加该包的类型,而不是替换它们。
但是,作为声明而不是扩充的 declare module
语句必须位于文件中,反之,也不是模块。也就是说,在包含任何顶级 import
或 export
语句的文件 not 中。
要解决此问题,请将 declare module 'vue-router' {...}
移动到一个单独的文件(例如,augmentations.d.ts
),并通过以 export {}
.[=25= 开头使该文件成为一个模块]
// augmenations.d.ts
// Ensure this file is parsed as a module regardless of dependencies.
export {}
declare module 'vue-router' {
interface RouteMeta {
// is optional
isAdmin?: boolean
// must be declared by every route
requiresAuth: boolean
}
}
现在回过头来看看问题的原代码
// shims-vue.d.ts
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
export default component;
}
declare module 'vue-router' {
interface RouteMeta {
isPublic?: boolean;
}
}
两个 declare module
语句不能存在于同一个文件中,因为其中一个试图声明一个模块,'*.vue'
,另一个试图扩充一个。因此,我们将 declare module '*.vue' {...}
保留在原处,因为它按预期运行。