如何在 Vue Router v4 中为自定义元字段声明 TypeScript 类型接口?
Posted
技术标签:
【中文标题】如何在 Vue Router v4 中为自定义元字段声明 TypeScript 类型接口?【英文标题】:How to declare TypeScript type interface for custom meta fields in Vue Router v4? 【发布时间】:2021-01-07 22:51:50 【问题描述】:Vue Router version 4,目前是in beta.11 in vue-router-next repo,有一个documentation page关于如何用TypeScript定义元字段自定义类型接口。 p>
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' 模块似乎可以做到这一点。
定义自定义元字段类型的正确方法是什么?
【问题讨论】:
因为他们的文档错误或不完整。正如所记录的那样,那个 sn-p 完全符合 你 所说的。它用您自己的声明代替'vue-router'
包的声明,而不是扩充它们。要解决此问题,请将declare module 'vue-router'
移动到一个单独的文件中,并通过以export
开头使该文件成为一个模块。这两个declare module
块不能存在于同一个文件中,因为其中一个试图声明一个模块,另一个试图增加一个。
感谢@AluanHaddad,这似乎已经解决了问题。将这些声明移动到单独的文件中。但是在declare module 'vue-router'
块之前添加export ;
语句如何将其从覆盖包的模块声明更改为扩充它?
我在答案中添加了一些文档链接。基本上含义上的区别是import
/export
将文件的含义从脚本更改为模块。声明和扩充的语法是相同的,但在一种情况下表示一件事,在另一种情况下表示另一件事。
【参考方案1】:
他们的文档是错误的,或者充其量是不完整的。
Module Augmentation 使用与Ambient Module 声明相同的语法,并且仅当它位于模块文件本身内时才被视为扩充。根据 ECMAScript 规范,模块被定义为包含一个或多个*** import
或 export
语句的文件。
非模块文件中的 sn-p 完全符合您所注意到的功能。它取代了 'vue-router'
包的任何其他类型,而不是扩充它们。但我们想增加该包的类型,而不是替换它们。
但是,旨在作为声明而非扩充的declare module
语句必须位于一个文件中,相反,该文件不是模块。也就是说,在一个文件中不包含任何***import
或export
语句。
要解决此问题,请将declare module 'vue-router' ...
移动到一个单独的文件(例如augmentations.d.ts
),并以export
开头使该文件成为一个模块。
// 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 v4 中为自定义元字段声明 TypeScript 类型接口?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中为自定义 DataTemplateSelector 获取 DataTemplate 的 x:DataType