The reason I ask this question is because I saw the following sentence in official document about module.
The core idea of the pattern is that the import id = require("...") statement gives us access to the types exposed by the module.
I am totally confused. Why module has a type? Why require() can give us the type exposed by the module?
TypeScript provides modules and namespaces in order to prevent the default global scope of the code and also to organize and maintain a large code base. Modules are a way to create a local scope in the file. So, all variables, classes, functions, etc. that are declared in a module are not accessible outside the module.
What is a type in TypeScript. In TypeScript, a type is a convenient way to refer to the different properties and functions that a value has. A value is anything that you can assign to a variable e.g., a number, a string, an array, an object, and a function.
The TypeScript declares module is one of the modules and keyword it is used for to surround and define the classes, interfaces; variables are also declared it will not originate with the TypeScript like that module is the set of files that contains values, classes, functions/methods, keywords, enum all these contains ...
import type only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there's no remnant of it at runtime. Similarly, export type only provides an export that can be used for type contexts, and is also erased from TypeScript's output.
At runtime, to another module importing it, a module is a JavaScript object with properties for each export. The set of properties on that object outline the type of the module. And of course TypeScript can know the types of those properties at compile time, just like it can know about other objects.
But from the module's own point of view, it is a function that gets executed to add properties to an exports
object passed to it. Generally speaking that exports
object becomes the module to its importers.
If that seems strange, then we need to look at the purpose of a module, which is to limit the scope of it's members. In JavaScript, the primary way of limiting the scope of something you are defining, is to define it inside a function.
The exact form of function for modules generated by TypeScript depends on the loader option you choose. With CommonJS modules for example (used by NodeJS) the function for a module gets automatically wrapped around a .js files's conents by the loader. For Node.js that function normally looks like this:
(function (exports, require, module, __filename, __dirname) {
<<JavaScriptFileContent>>
\n});
As part of the module loading process, Node.js compiles this anonymous function, then calls it, passing an (almost) empty JavaScript object for exports
, the require()
function, etc. Typically the code in the middle works by adding properties to the exports
object.
That's not quite the whole story, its possible for a module to be something else. If the code in the middle assigns something else to module.exports
, that object becomes the runtime module object. This isn't very common.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With