Gunchars
Gunchars

Reputation: 11066

Is it possible to have namespace declaration merging with any kind of imports?

I've been looking for some ways to cut down on the boilerplate for importing dependencies and stumbled upon Typescript namespaces and how they are merged across multiple files. For example:

foo.ts

namespace app {
  const foo = bar() // foo is 42 now
}

bar.ts

namespace app {
  export function bar() {
    return 42
  }
}

As long as both files are added to the Typescript project, it will compile fine and, depending on how it's bundled and/or executed, might even run fine (the order of the source files is important here). I find it refreshing that I don't have to type an import statement for every single dependency. Putting everything in a single namespace might have been crazy with plain Javascript, but I think it works like a charm with Typescript since it can keep track of all the symbols and where they're used.

Now, the pickle is that this only works as long as there are no import or export statements in any of the sources. The second I try to import an external library, that source file becomes its own module and the namespace no longer automatically merges with the other.

Using require still works, but there's no nice way to get the types for the import.

Any ideas how to use this namespace merging with external imports?

Upvotes: 2

Views: 1240

Answers (2)

Gunchars
Gunchars

Reputation: 11066

Here's one potential way to overcome the import problem I've found so far.

external.d.ts

import * as events from "events"
import * as ts from "typescript"

declare global {
  // if using @types/node
  interface NodeRequireFunction {
    (id: "events"): typeof events
  }
  // if declaring your own require function
  function require(id: "typescript"): typeof ts
}

In the main app code, just use the require function as usual.

main.ts

namespace app {
  // Both of these will be correctly typed
  const {EventEmitter} = require("events")
  const ts = require("typescript")
}

This adds some boilerplate, but at least it's only once per external module. The app code can export the required modules making them accessible everywhere.

Upvotes: 1

artem
artem

Reputation: 51769

No.

Each module in javascript, and therefore in typescript, is a separate, isolated namespace.

Having explicit import statement for every single dependency is what modular programming is all about. The intent is for each module to be a small, self-contained piece of code with minimum necessary dependencies. Many good node.js packages follow this style.

What you are describing looks completely different - when you have a large amount of code, it indeed may seem convenient to have access to everything from everywhere, without thinking about dependencies. Modules are not a good fit for this style, however.

Upvotes: 1

Related Questions