'Typescript: export all functions in a namespace
Lets say I have a typescript file Utils with a bunch of exported functions:
export function utilOne(){}
export function utilTwo(){}
I added index.d.ts file to this folder where I export * from the Utils file:
export * from './Utils';
In my other classes I'd like to access functions utilOne and utilTwo via utils namespace, like:
utils.utilOne();
I know that I can import it like this:
import * as utils from "./Utils";
However, as I will be using utils a lot, I would like to be able to export utils in a namespace, something like:
export {* as utils} from './Utils'; // this doesn't work
and then use:
import * from "./Utils";
However the export {* as utils} doesn't work. I could put all the functions of Utils to a module "utils" and export it, but I am not sure if this is a good practice. Is there a proper way to do this?
Solution 1:[1]
import * from
No. Global imports are considered bad practice even in languages that support them. (e.g. python Why is "import *" bad?)
JavaScript / TypeScript doesn't support it. After all its pretty useful to see foo.bar and know that bar is coming from foo instead of bar and having no clue where bar is coming from (without cloning and analyzing the whole project). ?
Solution 2:[2]
Since TC39/ecma 262 the feature you probably need was merged. So now you can export the module itself like this:
// module.ts
export interface Foo{
bar: string;
}
export function A(){
}
export function B(){
}
export * as MyModule from './module';
And then use it like a module that contains his own context:
import {MyModule} from './module';
type MyType = MyModule.Foo;
MyModule.A();
MyModule.B();
Seems to me it depends on TS version and webpack if you are using it. For me it's webpack 5 and TS v4.1.2 works good. Did not check tree-shaking yet, but looks it should work fine.
Solution 3:[3]
Caveats aside, depending on your project, one can accomplish this export utilizing a layer of indirection.
./utils/internal/utils.ts
export function utilOne(){}
export function utilTwo(){}
./utils/utils.ts
import * as utils from './internal/utils';
export utils;
./test.ts
import { utils } from './utils/utils';
utils.utilOne();
Caveats:
As noted, this is a questionable practice, and the desire to namespace may be indicative of a code-smell. It may also negatively impact the tree-shakability of your library and resulting projects.
Note: This structure is inspired by RxJS.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Zachary Moshansky |
