Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespaces vs modules vs typings in typescript?

Tags:

typescript

Can someone please explain the difference between these concepts with an example,I'm really confused,what's the use of having three of them when they all serve the same purpose?

like image 680
vennapusa Avatar asked Jun 12 '17 07:06

vennapusa


People also ask

What is the difference between namespace and modules in 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 .

What is the difference between module and namespace?

A module is a way which is used to organize the code in separate files and can execute in their local scope, not in the global scope. A namespace is a way which is used for logical grouping of functionalities with local scoping.

Should you use namespaces in TypeScript?

For most projects we recommend using external modules and using namespace for quick demos and porting old JavaScript code. TSLint has a predefined rule to avoid namespaces. The same opinion is found in many places around Stack Overflow: I wouldn't recommended namespace nor mixing it with module source code.

What is a namespace in TypeScript?

The namespace is used for logical grouping of functionalities. A namespace can include interfaces, classes, functions and variables to support a single or a group of related functionalities. A namespace can be created using the namespace keyword followed by the namespace name.


1 Answers

TL;DR

Modules and namespaces are two means of encapsulation - breaking your code into parts that make sense. New code should be written with modules, rather than namespaces.

Declaration files ("typings") are used to describe modules, namespaces, variables, type declarations, etc. without actually containing any runnable code. Declaration files just tell TypeScript about what things exist, and how you can use those things.

DefinitelyTyped hosts declaration files for different packages. Declaration files for a DefinitelyTyped package called foo-bar will be published as @types/foo-bar on npm.

Namespaces

These formalized a somewhat dated pattern in JavaScript. The pattern was basically wrapping code in an IIFE to prevent conflicts of declarations in the global scope. These things tacked "exports" onto an object and assigned them to a variable that (hopefully) had unique name in the global scope, like $ or _ or whatever.

As an example:

namespace foo {
    export var x = 10;
    export var y = 20;
}

This emits

var foo;
(function (foo) {
    foo.x = 10;
    foo.y = 20;
})(foo || (foo = {}));

Namespaces have other useful properties, like being able to merge with functions, classes, or other namespaces. But mainly, they were introduced during a transitionary period where it was necessary to serve both major ways to organize code: either providing the API surface on a well-known variable in the global scope (e.g. $, _, angular) or...

Modules

These all at once describe ECMAScript (standard JavaScript), CommonJS (i.e. Node.js), AMD (i.e. Require.js), and System.js modules. The crux of the idea here is that instead of just plopping variables into the global scope and hoping they don't conflict, each file gets its own unique scope and has exports.

In practice, the original implementations of modules (CommonJS, AMD, System.js) work the same way: wrap your code in a function to get the correct scope, and tack properties onto an object.

But TypeScript allows you to write code as if you were authoring ECMAScript modules with top-level export statements. Basically, to TypeScript, any file with top-level imports or exports is a module.

As an example, the following

export var x = 10;
export var y = 20;

translates to the following CommonJS module:

"use strict";
Object.defineProperty(module.exports, "__esModule", { value: true });
module.exports.x = 10;
module.exports.y = 20;

While namespaces have some useful use-cases, modules have become the clear way forward for breaking your code up into different pieces.

Typings/Types

"Typings" was a package manager for declaration files (.d.ts files) before @types became the prescribed way to get declaration files (more on this soon)

As a result, "typings" has also become a sort of nickname for declaration files.

If you are starting a new project, do not use Typings. The TypeScript ecosystem has largely standardized on using npm for declaration files. Additionally, because of the confusion in terminology, you should probably not call declaration files "typings".

With that said, we can move into the following topic:

Declaration files

Declaration files (.d.ts files, also called definition files) are TypeScript files that describe existing code. They can be produced from .ts files using the --declaration flag, or they can be authored manually to describe existing JavaScript code.

Declaration files contain declarations of the code that they actually describe. To be more specific, the following TypeScript function:

function foo(x: number, y: number) {
    return x * 100 + y;
}

would be described by the following declaration:

declare function foo(x: number, y: number): number

If the original declaration was written in JavaScript, it could still be described using a declaration with explicit types like above.

This is important because the vast majority of JavaScript code isn't originally authored in TypeScript. So the community has come together and created a repository of declaration files called DefinitelyTyped.

DefinitelyTyped

This is a big git repository that describes over 3000 libraries at the time of this writing. Users can send pull requests for fixes and new packages.

You can take a look at the repo here on GitHub.

@types and npm

This is how you can get declaration files from DefinitelyTyped. For example, if you wanted the .d.ts files for lodash, you could write

npm install @types/lodash

See

  • the consumption section of the TypeScript website on declaration files.
  • the announcement blog post titled The Future of Declaration Files
  • the elaboration of the above blog post

How do these relate?

Unfortunately the ideas here are subtle. Declaration files can describe everything in TypeScript. That means that they can describe what a module looks like, as well as what a namespace looks like.

So declaration files don't serve the same purpose as modules and namespaces. But they do describe to TypeScript when namespaces and modules exist, and how they can be used.

Basically, if you ever need to use something that looks like a module or a namespace and it was written in JS, you'll need a declaration file.

Even if it was written in TypeScript, if it was already compiled to .js, then you'll need a respective .d.ts file to use it.

I still don't understand

Hopefully this helped explain, but if not, check out

  • The modules section on the TypeScript website.
  • TypeScript Deep Dive's section on modules
  • the above resources
  • Ryan's weird candy cup analogy that describes the differences between modules and namespaces that cartant linked to above.
like image 199
Daniel Rosenwasser Avatar answered Oct 06 '22 14:10

Daniel Rosenwasser