当前位置: 首页 > 知识库问答 >
问题:

vue.js - 如何在Vue中解决TS类型错误:MenuOptionWithEx不是MenuOption的子类型?

司马作人
2024-03-07

TS 的 vue 项目中,有如下代码块简化如下:

<n-menu  :render-extra="renderMenuExtra"/>

其中,render-extra 报错为:
image.png

项目地址:https://github.com/lingkai5wu/link-admin
问题代码位于这里
类型位于这里

MenuOptionWithEx 是我扩展 MenuOption 的类型,相关信息如下:

type MenuOptionWithEx = MenuVO &  MenuOption & {    meta?: RouteMeta  }export interface MenuVO {  id: number  pid: number  type: MenuTypeEnum  label: string | null  path: string | null}// MenuOption 为 Naive UI 内置类型export type MenuOption = (MenuOptionSharedPart & {    /** @deprecated */    title?: string | (() => VNodeChild);}) | (MenuOptionSharedPart & {    label?: string | (() => VNodeChild);});// 同上export interface MenuOptionSharedPart {    key?: Key;    disabled?: boolean;    icon?: () => VNodeChild;    children?: Array<MenuOption | MenuGroupOption | MenuDividerOption>;    extra?: string | (() => VNodeChild);    props?: HTMLAttributes;    show?: boolean;    [key: string]: unknown;    /** @deprecated */    titleExtra?: string | (() => VNodeChild);}// RouteMeta 为 Vue Router 内置类型export declare interface RouteMeta extends Record<string | number | symbol, unknown> {}

我尝试使用联合类型扩展 MenuOptionWithEx,使 MenuOptionWithEx 为子类型,MenuOption 为父类型,期望满足 TS 的要求,但仍然报错,如上。
经过测试,我发现将 MenuOptionWithEx 中的 MenuVO 从联合类型中移除,就不会出现报错,但这不符合业务逻辑...

我也尝试直接继承 MenuOption,但 MenuOption 是联合类型,似乎没法直接继承。

共有1个答案

陈扬
2024-03-07

在 TypeScript 中,联合类型(Union Types)表示一个值可以是几种类型之一。在你的例子中,MenuOption 是一个联合类型,这意味着它可以是 MenuOptionSharedPart & { title?: string | (() => VNodeChild); }MenuOptionSharedPart & { label?: string | (() => VNodeChild); } 中的任何一种类型。

由于 MenuOption 是一个联合类型,你不能直接扩展或继承它。但是,你可以通过创建一个新的类型,该类型符合 MenuOption 的所有可能类型的要求,来解决这个问题。

你的 MenuOptionWithEx 类型已经尝试这样做,它结合了 MenuVOMenuOptionRouteMeta。然而,你遇到的问题可能是因为 MenuOptionWithEx 并没有完全符合 MenuOption 的所有可能形状。

一个可能的解决方案是,为 MenuOptionWithEx 创建两个版本,每个版本都对应 MenuOption 的一个可能类型。然后,你可以将这两个版本作为联合类型,以满足 MenuOption 的所有可能要求。例如:

type MenuOptionWithExTitle = MenuVO &  (MenuOptionSharedPart & {    title?: string | (() => VNodeChild);  }) & {    meta?: RouteMeta;  };type MenuOptionWithExLabel = MenuVO &  (MenuOptionSharedPart & {    label?: string | (() => VNodeChild);  }) & {    meta?: RouteMeta;  };type MenuOptionWithEx = MenuOptionWithExTitle | MenuOptionWithExLabel;

这样,MenuOptionWithEx 就成为了 MenuOption 的一个子类型,因为它可以匹配 MenuOption 的所有可能形状。然后,你可以尝试使用 MenuOptionWithEx 作为 renderMenuExtra 的类型,看看是否解决了你的问题。

请注意,这只是一个可能的解决方案,具体的解决方案可能需要根据你的代码库和 MenuOptionSharedPart 的定义进行调整。

 类似资料:
  • 我有一个FirebaseActions类,它为我做注册和登录工作。我在其中添加了一个getCurrentUser方法。我从我的主屏幕小部件调用这个函数。我需要将返回值(type= FirebaseUser)放入主屏幕的一个变量中,以访问loggedInUser.email。我的问题;有什么方法可以将FirebaseUser类型数据转换成Future类型变量?当我在HomeScreen而不是Fire

  • 在vue3和pinia使用ts type+sId+zId 三个都会报 “property type does not exist on object” 新补充 v1,v2...是接口返回来的,自己重新定义了新key,v1写在IUserState了没有报错,其他都飘红

  • //我正在尝试此代码,但它没有添加到firebase //它给出了这些错误 处理手势时引发了以下_TypeError:类型“List”不是类型“String”的子类型 抛出异常时,这是堆栈:#0个SharedReferences。getString(包:共享首选项/共享首选项。dart:98:35)#1 CheckItemInNot(包:e_shop/Store/storehome.dart:33

  • 我刚刚学会了如何在flutter中使用。在使用这个库之前,我用实现的webservice工作正常。 现在,在更改为使用后,出现了错误,无法解决此问题 错误是: _InternalLinkedHashMap不是“BuiltRegister”类型的子类型 我的服务器只获取移动电话号码,这是json响应结构: 我构建具有结构的寄存器: 终端返回中的命令成功,我没有任何问题,现在这是我的实现: 和拦截器实

  • 我有一个错误,当试图解析我的JSON并显示在文本中,而不是作为一个。 下面是我的JSON结构。 这是我的未来API异步。 这是我显示JSON的代码。 当我试图获取数据时,我得到了这样的错误。 我应该修复哪个代码?

  • 我想从listofTaskNotApprove类更新图像,它将documentsnapshot的对象传递到EditTaskNotApprove。在我更新图像之前,我需要显示特定的图像,用户将从列表中选择特定信息。问题是如何在新屏幕上显示图像的当前索引? ListofTasKnot接受类。 这里是EditTask类,我需要显示用户选择的图像的当前索引。 更新图像需要显示的图像这是当用户想要更新Lis