• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

解决typescript/monorepo下诡异的没办法扩展类成员的坑

武飞扬头像
渔夫正在掘金
帮助3

引言

一般情况下,在typescript中如果我们要为某个第三方库的类扩展类成员,可以采用如下方法:

// thirdLib.ts
class ModuleBase{

}

// myapp.ts
declare module "thirdLib" {
    interface ModuleBase {
        count():number
    }
}

只需要在工程中使用interface就可以为类扩展成员类型。

最近在为一个monorepo多包工程下使用typescript扩展类成员,遇到一个坑无法扩展类,至今也不知道是什么原因,读者如有知道的,请留言指点!

问题描述

  • typescript版本5.1.6
  • 包管理工具采用pnpm
  • 项目是一个monorepo工程,结构如下
myapp
  |--packages
     |-- core                 // 包名:@voerka/core
        |--src
          |-- module.ts       // 里面导出class ModuleBase
          |-- index.ts
     |-- app                  // 包名:@voerka/app
     |-- nodejs               // 包名:@voerka/nodejs
     |-- exchange            // 包名:@voerka/exchange
         |--src 
            |--types.ts      
            |--index.ts      // export * from "./types"
  |--examples
     |--testapp
          index.ts             
  • 以上appnodejsexchange均安装@voerka/corepeerDependencies
  • examples/testapp依赖于@voerka/core@voerka/nodejs,@voerka/nodejs依赖于@voerka/app
  • examples/testapp依赖@voerka/exchange
  • 然后在@voerka/exchange包的types.ts中,扩展了@voerka/core中的Class ModuleBase,如下:
declare module "@voerka/core" {
    interface ModuleBase { 
        count():number
    }
}

// 此处我们只讨论扩展类型,不考虑实现。

  • examples/testapp/index.ts内容如下:
import {ModuleBase} from "@voerka/core

class MyModule extends ModuleBase{
}

正常情况下,以下代码应该能够正常工作,我们通过interface ModuleBase 扩展了存在于@voerka/coreexamples/testapp/index.ts中的MyModule应该是继承了@voerka/core中的ModuleBase,并且具有一个count成员方法。

问题:

而我的项目中,以上扩展ModuleBase方法并不能生效,而是直接就提示无法扩展接口‘ModuleBase’。您的意思是‘实施’吗?ts(2689)错误。

我发现,在@voerka/exchange包的types.tsdeclare module "@voerka/core"interface ModuleBase覆盖了@voerka/core中的类声明,是覆盖类型定义,而不是合并,导致了ModuleBase从一个类变成了一个interface,从而无法进行类继承。

问题解决

为了解决此问题,我做了很多尝试:

  • chatGPT百度文心一言等均无法给出解决方案,或许是我问的方法有问题,或许是问题太复杂,没有得到有效的答案。
  • 生新构建了一个monorepo工程,但是却无法复现。
  • 一度怀疑是否class无法通过interface扩展。

最终无意中的一个举动解决了此问题,在声明模块时将@voerka/core 更改为@voerka//core


declare module "@voerka//core" {
    interface ModuleBase { 
        count():number
    }
}

小结

  • 当扩展模块名称是@xxxx/xxx形式时,可以将之声明@xxxx//xxx形式
  • 只所以说是诡异是因为,我完全重建一个monorepo工程,但是却无法复现。
  • 没找到官方或者哪里的文档说明这个小细节。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfheccg
系列文章
更多 icon
同类精品
更多 icon
继续加载