如何在 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 规范,模块被定义为包含一个或多个*** importexport 语句的文件。

非模块文件中的 sn-p 完全符合所注意到的功能。它取代了 'vue-router' 包的任何其他类型,而不是扩充它们。但我们想增加该包的类型,而不是替换它们。

但是,旨在作为声明而非扩充的declare module 语句必须位于一个文件中,相反,该文件不是模块。也就是说,在一个文件中包含任何***importexport 语句。

要解决此问题,请将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

如何在 WooCommerce 中为自定义产品数据选项卡定义图标

如何在 JavaScript 中为自定义对象创建方法?

如何在 iOS 中为自定义属性设置动画

如何在 Angular 中为自定义组件实现伪事件?

如何在 .NET 中为自定义配置部分启用 configSource 属性?