Exercise - Organize code by using single file namespaces
You can implement namespaces within a single TypeScript file or across multiple TypeScript files.
Note
You must use an IDE, such as Visual Studio Code, to implement multi-file namespaces. It is not possible to do this in the TypeScript Playground.
Complete the steps to define a single file namespace:
Open a new Visual Studio Code workspace.
Create a new file called module08_exercise.ts.
Define a new namespace by using the
namespace
keyword followed by the namespace name. You can define as many namespaces as needed within a single TypeScript file. At the top of the file, define two namespaces namedGreetings
andGreetingsWithLength
.namespace Greetings { } namespace GreetingsWithLength { }
You can now define functions and classes inside of the namespace definition. All components defined within the namespace are scoped to the namespace and removed from the global scope. Add a new function called
returnGreeting
to theGreetings
namespace. This function returns the value of a parameter to the console.namespace Greetings { function returnGreeting (greeting: string) { console.log(`The message from namespace Greetings is ${greeting}.`); } }
Add two new functions,
returnGreeting
andgetLength
, to theGreetingsWithLength
namespace. ThereturnGreeting
function uses the helper functiongetLength
to determine the length of the greeting before returning the message to the console.namespace GreetingsWithLength { function returnGreeting (greeting: string) { let greetingLength = getLength(greeting); console.log(`The message from namespace GreetingsWithLength is ${greeting}. It is ${greetingLength} characters long.`); } function getLength(message: string): number { return message.length } }
If you want to make a function or class available to code outside of the namespace, add the
export
keyword before its name. If you omit theexport
keyword, the component is only available inside the namespace. You can do this if defining components that should only be directly accessible to other components within the namespace. Add theexport
keyword to thereturnGreeting
function in both namespaces. ThegetLength
function should not be accessible outside of theGreetingsWithLength
namespace so omit theexport
keyword.namespace Greetings { export function returnGreeting (greeting: string) { console.log(`The message from namespace Greetings is ${greeting}.`); } } namespace GreetingsWithLength { export function returnGreeting (greeting: string) { let greetingLength = getLength(greeting); console.log(`The message from namespace GreetingsWithLength is ${greeting}. It is ${greetingLength} characters long.`); } function getLength(message: string): number { return message.length } }
To use a class or function within a namespace, prefix the component name with the namespace name. Try calling the
returnGreeting
function without specifying the namespace. This returns an error because bothreturnGreeting
functions are out of scope in the global namespace. Now, try prefixingGreetings
orGreetingsWithLength
to thereturnGreeting
function. This provides access to the function within each respective namespace.returnGreeting('Hello'); // Returns error Greetings.returnGreeting('Bonjour'); // OK GreetingsWithLength.returnGreeting('Hola'); // OK
Organize code using nested namespaces
You can also nest namespaces within namespaces, providing even more options for organizing your code.
Continue working in the code editor.
Create a new namespace called
AllGreetings
and then move theGreetings
andGreetingsWithLength
namespaces that you created previously inside it. Add theexport
keyword before both namespace names. This allows the namespace to be accessible outside of theAllGreetings
namespace.namespace AllGreetings { export namespace Greetings { export function returnGreeting (greeting: string) { console.log(`The message from namespace Greetings is ${greeting}.`); } } export namespace GreetingsWithLength { export function returnGreeting (greeting: string) { let greetingLength = getLength(greeting); console.log(`The message from namespace GreetingsWithLength is ${greeting}. It is ${greetingLength} characters long.`); } function getLength(message: string): number { return message.length } } }
To call the functions, start by typing the outermost namespace name,
AllGreetings
, a period, and then the next level in the namespace hierarchy,Greetings
orGreetingsWithLength
. Continue down the hierarchy until you reach the function name.AllGreetings.Greetings.returnGreeting('Bonjour'); // OK AllGreetings.GreetingsWithLength.returnGreeting('Hola'); // OK
Defining a namespace alias
TypeScript creates an easy-to-navigate hierarchy of nested namespaces. But, as your nested namespaces become more complex, you may want to create an alias to shorten and simplify your code. To do this, use the import
keyword.
Continue working in the code editor.
Type
import greet = AllGreetings.Greetings
. This defines a new alias calledgreet
that representsAllGreetings.Greetings
. You can now usegreet
in place ofAllGreetings.Greetings
in your code.import greet = AllGreetings.Greetings; greet.returnGreeting('Bonjour');
Compiling single file namespaces
You compile a single file namespace the same way that you compile any other TypeScript file. Because namespaces are a TypeScript-only construct, they are removed from the resulting JavaScript code and converted into variables that nest as necessary to form namespace-like objects.