基于Koa使用默认名称命名导出创建可扩展的打字稿包

时间:2018-11-12 14:09:56

标签: typescript

我正在创建一个扩展Koa并添加一些基本功能的模块,同时仍然可以由包的使用者扩展。事实证明,这非常具有挑战性,所以我希望有人对如何实现这一想法有所了解。

最终目标是在使用我的包时能够保留类型,如下所示:

// Note default and named export - I have also tried only having named exports
import MyKoa, { isAuth } from 'mykoa';
import Router from 'koa-router';

// How I try to augment MyKoa in the consumer apps
declare module 'mykoa' {

  // Doesn't work: cannot use namespace "MyKoa" as value
  namespace MyKoa {
    interface Options {
      isReady: boolean;
    }
  }

  // Doesn't work at all
  interface Options {
    isReady: boolean;
  }
}


const app = new MyKoa();
const router = new Router();

router.get('/', isAuth(), ctx => {
  ctx.body = ctx.app.options.isReady; // Typescript should know that (ctx.)app.options.isReady is a boolean
});
app.use(router.routes());

app.listen(3000);

当前我有2个文件:

src / lib / MyKoa.ts:

import Koa from 'koa';

// Augment Koa
declare module 'koa' {
  interface Application extends MyKoa {} // This ensures that MyKoa types are retained in koa-router middleware and works fine 
}

// My Koa class
class MyKoa extends Koa {
  public options: MyKoa.Options = {};
}

// Declare MyKoa namespace to hold relevant types
declare namespace MyKoa {
  interface Options {}
}

export = MyKoa;

src / index.ts:

import MyKoa from './lib/MyKoa';
import isAuth from './lib/isAuth';

export default MyKoa;
export { isAuth };

如果我声明带有文件完整路径的模块(例如,mykoa / dist / lib / MyKoa),我可以很好地扩展类型,但是我不希望包的使用者依赖于内部目录结构我的包裹。这有可能吗?有没有更好的方法来提供相同的功能?

1 个答案:

答案 0 :(得分:1)

以TypeScript当前known limitation的形式来扩展符号,使其以最初定义它的模块而不是重新导出它的模块为目标。我唯一建议的解决方法是将您希望mykoa的使用者使用的符号扩展到mykoa的主模块中。