Creating an extendable typescript package based on Koa with default and named exports










0















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?










share|improve this question


























    0















    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?










    share|improve this question
























      0












      0








      0


      0






      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?










      share|improve this question














      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?







      typescript






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 12 '18 at 14:09









      chredv12chredv12

      31




      31






















          1 Answer
          1






          active

          oldest

          votes


















          1














          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.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263917%2fcreating-an-extendable-typescript-package-based-on-koa-with-default-and-named-ex%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            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.






            share|improve this answer



























              1














              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.






              share|improve this answer

























                1












                1








                1







                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.






                share|improve this answer













                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.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 12 '18 at 21:11









                Matt McCutchenMatt McCutchen

                13.4k719




                13.4k719



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263917%2fcreating-an-extendable-typescript-package-based-on-koa-with-default-and-named-ex%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Use pre created SQLite database for Android project in kotlin

                    Darth Vader #20

                    Ondo