5

One of the problems of moment-timezone is that it gives you a warning if you include it multiple times. I have a module that requires the timezone. Because I don't know if whoever is using will or will not set the timezone themself, I have the following:

if (moment.tz === undefined) {
    require('moment-timezone');
    moment.tz.setDefault('America/Los_Angeles');
}

This works fine in normal Javascript. I recently was experimenting to switch to Typscript, and when I do this, I get the error that Cannot find name 'require'.

I switched that line to import momentTimezone = require('moment-timezone'); but then get An import declaration can only be used in a namespace or module.

What can I do?

Kousha
  • 32,871
  • 51
  • 172
  • 296
  • 1
    I think this could help you out: http://stackoverflow.com/questions/12742082/nodejs-require-inside-typescript-file – Matthijs Dec 23 '16 at 08:07
  • @Matthijs, no I originally saw that (that's where the `import momentTimezone =...` attempt came from). But that also doesn't work :( – Kousha Dec 23 '16 at 18:03
  • What is the execution context for this code? If this is in the browser, you need to have a module loader available in order to make sure require is defined. If this is in node, you need to either install typings for the require function (through require or node) OR declare that function typing like in the post @Matthijs referenced – Paarth Dec 27 '16 at 23:01
  • The reason the import fails is because the import syntax is some extra stuff that's TS specific. This lets TS compile down to the various dependency spec formats depending on the module configuration in the tsconfig. It would be the same as if you were using ES6 style imports (`import {...} from '...'`). Dynamic requires necessitate using the require function as a loader-specific function. – Paarth Dec 27 '16 at 23:04

1 Answers1

5

The import foo = require ('foo') is typescript specific. It does two things , import the type definitions to the declaration space and the actual module to the variable space. If you don't use the imported module at any point and only use it for typings then it will be removed at runtime . But if you use it on the variable namespace, e.g., calling a method or assigning it to a variable then you will get a runtime import . Knowing this is very important because it will save you surprised .

If you want to import and use the type definitions and only import the actual module if some condition is met, then you have to combine typescript's import with the regular require like this:

import foo = require('foo');

export function loadFoo() {
// This is lazy loading `foo` and using the original module *only* as a type annotation
    var _foo: typeof foo = require('foo');
    // Now use `_foo` as a variable instead of `foo`.
}
Denis Howe
  • 2,092
  • 1
  • 23
  • 25
Danielo515
  • 5,996
  • 4
  • 32
  • 66