TypeScript error TS2449: Class 'x' used before its declaration

Major Terminology Alert

Namespaces are not preferred over modules. This is a very important point. Let's dive into the history...

Namespaces used to be declared like this:

module MyNamespace {

}

But they are now declared like this:

namespace MyNamespace {

}

When declaring a namespace, the namespace keyword is preferred to the old module keyword.

The reason the module keyword was replaced with namespace is that people confused them with "modules". You can see where the confusion might come from! Now actual modules (i.e. files that export or import something) are actually a bit better than namespaces, which is why I have spent the entire answer so far covering all this.

Use Modules

With this in mind, you might consider using modules. Each module gives you a naming context and keeps stuff out of the global scope. You can import and export and everything should work as expected (and you can still bundle it if you like).

src/base.ts

export class Base {

}

src/subclass.ts

import * as Example from './subclass.ts';

export class Base extends Example.Base {

}

Namespace Merging

If you want to stick with namespaces, you have to respect that everything you place within a namespace (even when that namespace is spread across multiple files) contributes to a single naming context... so you'll have to name the subclass differently.

src/base.ts

namespace MyNameSpace {
  export class Base {
     /** constructor, etc. */
  }
}

src/subclass.ts

/// <reference path="./base.ts" />

namespace MyNameSpace {
  export class Sub extends Base {
     /** constructor, etc. */
  }
}

So ultimately, you can choose modules (proper external modules) where each file has its own naming context, and you can easily avoid naming collisions - or namsepaces where you'll need to be aware that each namespace is a single naming context.

Small Print

In may examples I have inherited Base in the subclass for illustration. You're question didn't exactly do that, but I wanted to illustrate the concept. The question had two classes within the namespace with the same name, which is a duplicate name conflict.


I was able to resolve this error by restarting Visual Studio as mentioned in the comments by @Quentin2

Tags:

Typescript