2

I would like to define typing for a Javascript project. Let's consider a simplified version:

a
|
+ A.js
+ b
  |
  + B.js 

There is a folder 'a', and inside it there is folder 'b', and I would like to use it as:

import { A } from "a"
import { B } from "a/b" 

The typing that I ideally would like to have looks like something like this:

declare namespace a {
    interface A { }

    namespace b {
        interface B { }
    }
}

declare module "a" {
    export = a
}

declare module "a/b" {
    export = a.b
}

However, this gives me the error Cannot use namespace 'a' as a value.

I noticed if I change interfaces to classes, the problem resolves. Can someone please shed some light why it is like that? Is there a way to get such definitions with interfaces?

1 Answer 1

3

https://github.com/Microsoft/TypeScript/issues/17530

A namespace that contains no values or statements is considered an uninstantiated namespace, and has no runtime value.

You can prevent the error by doing:

declare module "a/b" {
    import b = a.b
    export = b
}

However, unless the namespaces a and a.b are actually available as globals at runtime, you should write:

declare module "a" {
    export interface A {
        foo: string
    }
}

declare module "a/b" {
    import {A} from 'a'
    export interface B {
        bar: A
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

What do you mean by "unless the namespaces a and a.b are actually available as globals at runtime"?
@Wickoo i.e. you can access them without importing them, like setTimeout

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.