Typescript: Add module option called "omit"

Created on 10 Jan 2017  ·  11Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 2.1.4

Add module option called "omit"

example tsconfig.json:

{
  "compilerOptions": {
    "module": "omit"
  }
}

This would not output any of the module import statements. Eg:

// start imports
import * as $ from 'jquery';
import * as _ from 'lodash';
// end imports

Would output import statements to javascript as no code at all:

// start imports
// end imports

instead of:

// start imports
var $ = require('jquery');
var _ = require('lodash');
// end imports

This will be useful for people that have an existing frontend project.
The'll be able to use the benefits of Typescript including external modules with type checking like Lodash and jQuery without having to setup a module loader on the client side (require.js), or package their Javascript in a build process (webpack or browserify).
Using this approach will require adding the packages manually to the html files. Eg:

<html>
  <head>
    <script src="node_modules/lodash/index.js"></script>
    <script src="node_modules/jquery/index.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

If you currently want to do this you have to include a hack like this to neutralize the require statements. Which causes a wanrning (TS2441: Duplicate identifier 'require'. Compiler reserves name 'require' in top level scope of a module.).

function require(moduleName: string) {
  switch (moduleName) {
    case 'jquery':
      return $;
    case 'lodash':
      return _;
  }
}

Some other people that have the same issue:
http://stackoverflow.com/questions/39854655/typescript-and-react-outputting-require

Question

Most helpful comment

Try not using modules at all. If you don't have any imports/exports everything is considered global scope and works the way you described.

All 11 comments

Try not using modules at all. If you don't have any imports/exports everything is considered global scope and works the way you described.

But then I don't get code completion for 3rd party library, right?

... have you tried?

@bertyhell to clarify, you should, even using the mechanism of installing from @types. If you don't get completions for the libraries you're using, try adding the name of the package to the "types" field in your tsconfig.json's "compilerOptions" field.

For example:

{
    "compilerOptions": {
        "types": ["jquery", "lodash"]
    }
}

This will force TypeScript to try to grab the declarations for jquery and lodash.

Just for completeness sake: @DanielRosenwasser suggestion is the new and better approach (for TypeScript >= 2.0). In older versions @types were not a thing and you had 2 options:

  • either use reference directives (in any file, it will work from then on everywhere)
  • or put the declaration file among files in tsconfig.json or directly pass it to the compiler

Ok, i tried this out:

Reference: When i use the fake require function and import statements

function require(moduleName: string) {
  switch (moduleName) {
    case 'jquery':
      return $;
    case 'lodash':
      return _;
  }
}

import * as $ from 'jquery';
import * as _ from 'lodash';

Result: Correct autocomplete in intellij and typechecking
image

Attempt 1: tsconfig types

{
    "compilerOptions": {
        "types": ["jquery", "lodash"]
    }
}

Result: No autocomplete but i do get correct type checking
image

Attempt 2: Reference directives

/// <reference path="../../../node_modules/@types/lodash/index.d.ts" />
/// <reference path="../../../node_modules/@types/jquery/index.d.ts" />

Result: No autocomplete but i do get correct type checking
image

Attempt 3: put the declaration file among files in tsconfig.json

{
  "include": [
    "node_modules/@types/**/*.d.ts",
    "js/**/*.ts"
  ]
}

Result: No autocomplete but i do get correct type checking
image

Conclusion

It seems typescript would still benefit from an "omit" option for modules so that autocomplete can work in IntelliJ and maybe other IDE's as well

Why are you using modules if you want to use $ as global?

just use it as a global. you do not need any /// <references....

npm install @types/jquery
echo $("p").add("div").addClass("widget"); > a.ts
tsc 

Why are you using modules if you want to use $ as global?

Because then i don't get any autocompletion in my IDE
Did you read my last reply?

This seems to be a problem with webstorm. i would recommend filing this issue on their issue tracker. Here is what i see with VSCode.

animation

ok, will do

I was trying to define my own require function, which doesn't exist in the JavaScript runtime I'm working on (Adobe Animate / JSFL) and came across this issue. (due to error Compiler reserves name 'require' in top level scope of a module.)

I've managed to define my own require function this way (simplified version):

this['require'] = function(modulePath) {
    let exports = {};
    // ... evaluate the module
    return exports;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

siddjain picture siddjain  ·  3Comments

Antony-Jones picture Antony-Jones  ·  3Comments

manekinekko picture manekinekko  ·  3Comments

MartynasZilinskas picture MartynasZilinskas  ·  3Comments

fwanicka picture fwanicka  ·  3Comments