9
votes

I'm having some issues with getting a namespace across files to resolve and compile properly. According to documentation and this SO answer, the following should produce no issue:

App.Core.ts

namespace App.Core {
    export function createElem(tagName: string): JQuery {
        return $(document.createElement(tagName));
    }
}

App.Core.SubModule.ts

/// <reference path="App.Core.ts" />
namespace App.Core.SubModule {
    export function Test(): JQuery {
        return App.Core.createElem("div");
}

However, Visual Studio is giving me an error on the function call in App.Core.SubModule.Test stating Property 'createElem' does not exist on type 'typeof Core' My understanding is that if a namespace is across multiple files TS compiler will automatically resolve those namespaces. It looks like the corresponding JavaScript is coming out correct however the lack of intellisense (and the red squiggle error line) is exceptionally frustrating and making me second guess what I'm writing.

Is this an issue with my file setup, with TS compiler, or with Visual Studio 2015's apparently broken TypeScript intellisense functionalities right now?

2
This code compiles fine on Webstorm. I suspect that the ordering of the files in the combined output makes a difference. Have a look at it. Anyway, If you can, move away from namespaces and use external modules. This will save you a lot of these types of headaches - Bruno Grieder
Followed your advice and used external modules instead. Typescript is still a very foreign idea to me. Took a little bit of searching and digging to realize that Typescript's output doesn't run in a browser without other resources like require.js. Definitely had a hard time deciphering and finding that on the TS documentation. But thank you for the help! Finally can get moving on the next part of my project! - willwolfram18

2 Answers

7
votes

Visual Studio is giving me an error on the function call in App.Core.SubModule.Test stating Property 'createElem' does not exist on type 'typeof Core'

Suspect you have a root level import or export in either of the files. That makes the file a module and disconnects it from the global namespace.

Quick Fix

Remove that import / export but be warned that it can lead to more problems https://basarat.gitbooks.io/typescript/content/docs/tips/outFile.html

Proper Fix

Don't use namespace. Just use modules : https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

1
votes

File A

namespace A {
  export type User = {
    name: string,
    age: number
  }
}

File B

namespace A {
  export type Goods = {
    city: string,
    price: number
  }
}

File C - merge namespaces here

declare module 'Final' {
  import 'namespace-b';
  import 'namespace-a';
}

File index.ts

import './namespace-final;';

function multipleNamespaces() {
  let user: A.User | A.Goods | undefined;
  user = { name: '', age: 0 }; // valid
  user = {city: 'beijing', price: 100} // vlaid
  user = 'test' // invalid
}