skiabox skiabox - 2 months ago 43
TypeScript Question

How to properly import a namespace in a Typescript project?

I am watching a video tutorial and I have created a a new typescript project.
First I created in the root directory the following namespace (utilityFunctions.ts) :

namespace Utility {

export namespace Fees {
export function CalculateLateFee(daysLate: number): number {
return daysLate * .25;
}
}

export function MaxBooksAllowed(age: number): number {
if (age < 12){
return 3;
}
else {
return 10;
}
}

//function that is not exported
//use it only inside the namespace
function privateFunc(): void {
console.log('This is private...');
}

}


Then I created another typescript file (app.ts) to use the above namespace code :

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


let fee: number = Utility.Fees.CalculateLateFee(10);
console.log(`Fee: ${fee}`);


When I run the app.js file (using webstorm latest version) I am getting the following error :

/Users/Administrator/.nvm/versions/node/v6.5.0/bin/node /Users/Administrator/WebstormProjects/NamespaceDemo/app.js
/Users/Administrator/WebstormProjects/NamespaceDemo/app.js:5
var fee = Utility.Fees.CalculateLateFee(10);
^

ReferenceError: Utility is not defined
at Object.<anonymous> (/Users/Administrator/WebstormProjects/NamespaceDemo/app.js:5:24)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3

Process finished with exit code 1


My tsconfig.json file is the following :

{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true
},
"exclude": [
"node_modules"
]
}


And my tslint.json file is the following (although I don't think that the linter has anything to do with compilation errors):

{
"extends": "tslint:recommended",

"rules": {
"comment-format": [false, "check-space"],
"eofline": false,
"triple-equals": [false, "allow-null-check"],
"no-trailing-whitespace": false,
"one-line": false,
"no-empty": false,
"typedef-whitespace": false,
"whitespace": false,
"radix": false,
"no-consecutive-blank-lines": false,
"no-console": false,
"typedef": [true,
"variable-declaration",
"call-signature",
"parameter",
"property-declaration",
"member-variable-declaration"
],
"quotemark": false,
"one-variable-per-declaration": false,
"max-line-length": 160,
"object-literal-sort-keys": false,
"trailing-comma": false,
"variable-name": [true,
"ban-keywords",
"check-format",
"allow-leading-underscore"
]
}

}

Answer

As your utilityFunctions.ts is already a module then there's no need to wrap what's inside of it in a namespace.

Also, using /// <reference ... is just for the compiler but node won't use it and so it doesn't know where to find utilityFunctions.
You need to import it.

Here are how the files should look:

export namespace Fees {
    export function CalculateLateFee(daysLate: number): number {
        return daysLate * .25;
    }
}

export function MaxBooksAllowed(age: number): number {
    if (age < 12){
        return 3;
    }
    else {
        return 10;
    }
}

//function that is not exported
//use it only inside the namespace
function privateFunc(): void {
    console.log('This is private...');
}

And:

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

import * as Utility from "./utilityFunctions"

let fee: number = Utility.Fees.CalculateLateFee(10);
console.log(`Fee: ${fee}`);

You can also completely remove the /// <reference as the compiler can find the .ts file when importing.