在手写的 d.ts 文件中,如何从模块根目录中的一个命名空间公开函数?

Her*_*ill 5 typescript typescript-declarations typescript-namespace

我正在开发一个全部使用 javascript 但导出手写类型声明(automerge/index.d.ts)的存储库。

代码库的结构是它有一个 Frontend 和一个 Backend,加上一个公共 API,除了直接从 Frontend 和 Backend 重新导出一些函数外,还提供了一些自己的便利功能。

像这样的东西:

declare module `foo` {

  // functions that only exist in the public API
  function a
  function b
  function c

  // functions exposed directly from namespace A
  function q
  function r
  function s

  // functions exposed directly from namespace B
  function x
  function y
  function z

  namespace A {
    function q
    function r
    function s
    function t
  }

  namespace B {
    function v
    function w
    function x
    function y
    function z
  }

}
Run Code Online (Sandbox Code Playgroud)

这是实际代码的摘录,显示了我们当前如何为重新导出的函数编写重复声明。

declare module 'automerge' {
  ...

  function getObjectById<T>(doc: Doc<T>, objectId: OpId): Doc<T>
  
  namespace Frontend {
    ...

    function getObjectById<T>(doc: Doc<T>, objectId: OpId): Doc<T>
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

有没有办法避免两次编写这些声明?

mih*_*ihi 0

一种可能性是定义一个箭头函数类型别名并在两个地方使用它。例如:

declare module "automerge" {
    type GetObjectById = <T>(doc: Doc<T>, objectId: OpId) => Doc<T>
    
    const getObjectById: GetObjectById

    namespace Frontend {
        const getObjectById: GetObjectById
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,无法直接使用“常规”函数声明执行相同的操作(请参阅此处)。

箭头函数和函数声明并不完全相同this,尤其是函数内的作用域。例如箭头函数不能有this参数:

// not allowed
const fn = (this: SomeContext) => void
// allowed
function fn(this: SomeConext): void
Run Code Online (Sandbox Code Playgroud)

但是,如果您不依赖于它们不同的任何功能,或者为了安全起见可以切换到 js 代码中的箭头函数,那么这应该可行。