Reputation: 3
I am creating a module that extends Koa and adds some basic functionality, while still being extendable by the consumers of the package. This is proving to be very challenging so I hope someone has an idea on how this can be done.
End goal is to be able to retain types while using my package like this:
// 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);
Currently I have 2 files:
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 };
I can extend the types fine if I declare the module with full path to the files (e.g. mykoa/dist/lib/MyKoa), but I don't want the consumer of the package to rely on the internal directory structure of my package. Is this even possible? Is there a better way of providing the same functionality?
Upvotes: 0
Views: 318
Reputation: 30949
The requirement for augmentations of a symbol to target the module that originally defines it and not a module that re-exports it is a current known limitation of TypeScript. The only workaround I can suggest is to move the symbols that you intend consumers of mykoa
to augment into the main module of mykoa
.
Upvotes: 1