首页 > 解决方案 > TS typings: How to access to namespace inside module?

问题描述

While using Typescript at work I encountered many dependencies that doesn't have the typings, both in project or in @types on NPM. While for some I was able to create on my own, in the case of youbora (here is the public source code @ bitbucket), a QA library for video players, I cannot create them: particularly I get stuck with namespaces.

Youbora let the developer to use it by creating a Plugin and registering an adapter.

import * as youbora from "youboralib";
import "youbora-adapter-shaka";

// ---- in my classes ----

this.youbora = new youbora.Plugin({ ... });

In another class/component (we are using react with typescript):

this.props.youbora.setAdapter(
    new youbora.adapters.Shaka(document.getElementById("videoContent"))
);

Typescript tells me that "youboralib" (which is the package name on NPM) has no declarations files. So I created it looking at the source code.

declare module "youboralib" {
  class Plugin {
    constructor(options: YouboraNS.PluginOpts, adapter?: YouboraNS.Adapter);
    setAdapter(adapter: YouboraNS.Adapter): void
    // ...
  }

  namespace adapters {}

  namespace YouboraNS {
    interface PluginOpts {}
    interface Adapter {
      plugin: any
    }
    interface Communication {}
  }
}

As we only include Plugin class, there are no problems.

Youbora.adapters, per the source code, is an empty object that gets populated by the imported adapters (like above, youbora-adapter-shaka). So it is possible to do, as above, new youbora.adapters.Shaka(...).

In terms on typings, it should be a namespace (as written). The problem is that if I declare a namespace in the module, I cannot access to it from the outside but only from the inside (as YouboraNS): in fact, VSCode suggests me only Plugin class. I made different searches across the web and SO but got no results.

So the problem here is: how can I access to a module-specific namespace?

To bypass this problem, I had to disable the flag tsconfig.CompilerOptions.noImplicitAny and / or use @ts-ignore above the instructions, but they are a so ugly solutions.

========================

If you look at the code of youboralib.js, you can see that actually "youbora" can be considered as a namespace itself, as it is an object with different properties.

So I tried to define it as a namespace, but still VSCode doesn't recognize it as a module:

export = youboralib;
export as namespace youboralib;

declare namespace youboralib {
  class Plugin { ... }
  namespace adapters {}
}

I tried also with export namespace adapters {} or something like this but got nothing different.

Any ideas? Thank you.

标签: typescripttypescript-typings

解决方案


推荐阅读