Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript namespace merging across files

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?

like image 331
willwolfram18 Avatar asked Sep 12 '16 13:09

willwolfram18


People also ask

Are namespaces global TypeScript?

Namespaces are a TypeScript-specific way to organize code. Namespaces are simply named JavaScript objects in the global namespace. This makes namespaces a very simple construct to use. Unlike modules, they can span multiple files, and can be concatenated using outFile .

Should you use TypeScript namespaces?

Don't use Custom TypeScript Modules and Namespaces Since we have ES6 modules as a standard in JavaScript, we don't need custom TypeScript modules and namespaces to organize our code. Instead, we should use standard JavaScript modules with import and export instead.

How do I combine two interfaces in TypeScript?

Merging Interfaces At the most basic level, the merge mechanically joins the members of both declarations into a single interface with the same name. let box: Box = { height: 5, width: 6, scale: 10 }; Non-function members of the interfaces should be unique. If they are not unique, they must be of the same type.

What is declaration merging in TypeScript?

In Typescript, the term “declaration merging” refers to the compiler combining two declarations with the same name into a single definition. Both of the initial declarations are present in this combined definition. It is possible to merge Interfaces, namespaces and enums and so on but classes cannot be merged.


2 Answers

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

like image 158
basarat Avatar answered Oct 12 '22 23:10

basarat


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
}
like image 41
Kay Saith Avatar answered Oct 13 '22 01:10

Kay Saith