Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript 2 — using ES6 import & require?

I have an exported class in my working Angular2 app using ES6 module:

//File = init.todos.ts

export class Init {
   load() {
      ...
    }
}

I'm importing this class from another component via :

//File = todo.service.ts

import { Init } from './init.todos'

It works as expected.

However if I change the loading mechanism to commonjs :

//File = init.todos.ts
export class Init {
    load() {
       ...
    }
}
 module.exports.Init = Init;

Requiring it:

//File = todo.service.ts
var  Init = require("./init.todos");

— I get those errors :

...myApp/src/app/todo.service.ts (4,13): Cannot find name 'require'.) ...myApp/src/app/todo.service.ts (12,14): Property 'load' does not exist on type 'TodoService'.)

enter image description here

Question:

How can I also load commonjs modules using require ?

Tsconfig.json:

{
    "compileOnSave": false,
    "compilerOptions": {
        "outDir": "./dist/out-tsc",
        "baseUrl": "src",
        "module": "system",
        "sourceMap": true,
        "declaration": false,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es5",
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2016",
            "dom"
        ]
    }
}

Here are the config files :

tslint.json

tsconfig.json

package.json

angular-cli.json

webpack.config.js

like image 712
Royi Namir Avatar asked Sep 08 '26 12:09

Royi Namir


1 Answers

Since version 1.5, Typescript has adopted the ES6 style of imports.

You can keep your code "as is"

//File = init.todos.ts

export class Init {
   load() {
      ...
    }
}

//File = todo.service.ts

import { Init } from './init.todos'

By moving the property module in tsconfig.json to commonjs, the transpiler will generate commonjs compatible javascript which will allow you to benefit from, and contribute to, the full nodeJS ecosystem.

"compileOptions": {
    ...
    "module": "commonjs"
    ...
}

If you wish to import an existing NodeJS module in your typescript code, a few things may happen

  • the module ships with embedded Typescript Definition Files (there is a "typings" entry in "package.json"). In that case, import the module using the ES6 syntax and you are good to go (import * as blah from 'blah'). immutable.js is a good example of such a library

  • the module does not ship with Definition files but there is one available on DefinitelyTyped, simply

    • run npm install @types/blah to get the definitions in your project
    • and import the module as usual: import * as blah from 'blah'
  • the module does not have a definition file

    • you can craft one, simply add it to your project after naming it blah.d.ts. DefinitelyTyped has a guide on this
    • you can decide to go without typings, simply use NodeJS require() const blah = require('blah'), and blah will have type any (which really means that blah opted out of typing)

(for sake of completeness, I could add the allowJS compiler option available since 1.8, but that is a whole subject in itself)

like image 192
Bruno Grieder Avatar answered Sep 11 '26 02:09

Bruno Grieder