Takeshi Tokugawa YD
Takeshi Tokugawa YD

Reputation: 915

How to re-export the child namespace in TypeScript?

I want to re-export the nested namespace HTML_Validator.Localization, but avoid the exporting of whole HTML_Validator, the meged entity.

class HTML_Validator {
    // ...
}


namespace HTML_Validator {

    export namespace Localization {

        export type FileIsEmptyWarningLog = Readonly<Pick<WarningLog, "title" | "description">>;

    export namespace FileIsEmptyWarningLog {
      export type NamedParameters = Readonly<{ targetFileRelativePath: string; }>;
    }

    }

}


export default HTML_Validator;

The re-export is required for other packages, but the functionality of HTML_Validator class is not required for them - I need to export the child namespace Localization only.

Below code is invalid but expesses what I want to do.

import HTML_Validator from "PATH/TO/HTML_Validator";
import HTML_ValidatorLocalization = HTML_Validator.Localization;

export HTML_ValidatorLocalization; // invalid: Cannot use namespace 'HTML_ValidatorLocalization' as a value.

Upvotes: 1

Views: 2425

Answers (2)

MBuchalik
MBuchalik

Reputation: 230

I see two options here:

  1. Explicitly export the nested namespace
  2. Extract the nested namespace

Option 1

When working with namespaces, you can use the import keyword to create aliases, see https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases. In my experience, this is one of the places where you can easily confuse (even experienced) developers, because the import keyword in this context is basically the equivalent of the var keyword - it has nothing to do with importing from modules or the like.

In your case, you can use it like so:

export namespace HTML_Validator {
  export namespace Localization {
    export type FileIsEmptyWarningLog = Readonly<Pick<WarningLog, "title" | "description">>;
  
    export namespace FileIsEmptyWarningLog {
      export type NamedParameters = Readonly<{ targetFileRelativePath: string; }>;
    }
  }
}

export import Localization = HTML_Validator.Localization;

Now, it is possible to import the Localization namespace in other places using import { Localization } from './my-html-validator';

Option 2

You could also explicitly extract the nested namespace, i.e. you could create a separate namespace like HTML_Validator_Localization, and reference it inside your HTML_Validator namespace. Then, similar to Option 1, you can import HTML_Validator_Localization using a named import from any other file.

export namespace HTML_Validator {
  export import Localization = HTML_Validator_Localization;
}

export namespace HTML_Validator_Localization {
  export type FileIsEmptyWarningLog = Readonly<Pick<WarningLog, "title" | "description">>;

  export namespace FileIsEmptyWarningLog {
    export type NamedParameters = Readonly<{ targetFileRelativePath: string; }>;
  }
}

Again, we are using the import keyword here to declare the alias.

Note

If you are using eslint, you might run into issues with the no-unused-vars rule. See https://github.com/typescript-eslint/typescript-eslint/issues/4129

Upvotes: 3

Jeffrey Rennie
Jeffrey Rennie

Reputation: 388

Is de-nesting the namespaces an option? In other words, creating a HTML_Validator_Localization namespace in a separate file and then importing it from both existing source files?

If not, the only variation I could get the typescript compiler to accept is replacing export HTML_ValidatorLocalization; with export default HTML_ValidatorLocalization;, but that may not work in your circumstance.

Upvotes: 1

Related Questions