title: Use Typescript declared module inside own declaration file
body: <p>My Javascript is running inside V8, which has a module <code>foo:bar/baz</code> available for import which is resolved by C++. I'm trying to write Typescript definitions for this module, so clients can interface with it in a type safe manner.</p>
  <p>Here is the actual specification that I'm describing (in pseudo-code):</p>
  <pre><code>module 'foo:bar/baz' {
      ENUM1 // A magic object of unique but unknown value.
      ENUM2 // Same
      ENUM3 // Same
      doSomething(): MyClass
      // where MyClass has a member function that returns one of the above enums.
  }
  </code></pre>
  <p>My goal is to provide type declarations for this module without exposing additional types or functionality that do not exist in the module.</p>
  <p>Here is my declaration file:</p>
  <pre><code>declare module 'foo:bar/baz' {
      export const ENUM1: unique symbol;
      export const ENUM2: unique symbol;
      export const ENUM3: unique symbol;
  
      // Unexported because there is no MyEnum in the true module.
      export type MyEnum = typeof ENUM1 | typeof ENUM2 | typeof ENUM3;
      export function doSomething(): MyClass;
  }
  
  declare interface MyClass {
      member(): MyEnum;
  }
  </code></pre>
  <p>And my usage of this module is:</p>
  <pre><code>import * as baz from 'foo:bar/baz';
  
  /** @type MyClass */
  const x = baz.doSomething();
  </code></pre>
  <p>The issue right now is that <code>MyEnum</code> is not available in the scope of <code>declare class MyClass</code> as it lives in the <code>foo:bar/baz</code> module. I've tried adding <code>import { MyEnum } from 'foo:bar/baz'</code> between the module and class declarations, but my linter says that module cannot be found.</p>
  <p>If I change the declaration to be:</p>
  <pre><code>declare module 'foo:bar/baz' {
      export const ENUM1: unique symbol;
      export const ENUM2: unique symbol;
      export const ENUM3: unique symbol;
  
      export type MyEnum = typeof ENUM1 | typeof ENUM2 | typeof ENUM3;
      export function doSomething(): MyClass;
  
      interface MyClass {
          member(): MyEnum;
      }
  }
  </code></pre>
  <p>Then <code>MyEnum</code> does resolve in the scope of <code>MyClass</code>, however, now my type checker does not recognize any methods on <code>x</code>, as there is no <code>MyClass</code> in the scope of my usage, only <code>baz.MyClass</code>.</p>
  <p>If I change my annotation to <code>@type baz.MyClass</code>, then the type checker does show methods on <code>x</code> however now the assignment is invalid with the error <code>Initializer type MyClass is not assignable to variable type baz.MyClass</code>.</p>
  <p>Two questions here:</p>
  <ol>
  <li>Is this just a failure of the WebStorm type checker to properly recognize that these classes are the same type?</li>
  <li>Is there a way around this? If I could change my module declaration to <code>declare module Baz</code>, then I could leave <code>declare class MyClass</code> outside the module and reference <code>MyEnum</code> instead as <code>Baz.MyEnum</code> and everything would resolve correctly. However, the module <em>must</em> be named <code>foo:bar/baz</code>. Is there a way I can dereference this module to the exported <code>MyEnum</code> member?</li>
  </ol>
  <p>The only workaround I've been able to find is to use the second declaration mentioned and change my usage to:</p>
  <pre><code>import * as baz from 'foo:bar/baz';
  import { MyClass } from 'foo:bar/baz';
  
  
  /** @type MyClass */
  const x = baz.doSomething();
  </code></pre>
  <p>This yields proper type resolution of <code>x</code> without a type error on the assignment. However, <code>foo:bar/baz</code> does not have a <code>MyClass</code>, as mentioned at the beginning, so my understanding is that this import would fail to resolve.</p>