Empty Set
Empty Set

Reputation: 35

Proper steps/syntax to import a library into a typescript file with a namespace in it

I am using Typescript with Nodejs, Windows 7 Ultimate x64. Compiler is tsc.

I am modifying an existing codebase which has many files sharing a namespace. So, at the top of each file there is a declaration like so:

namespace program {
    ...
}

I am trying to get the library JSZip working in this existing codebase, but I was running into some weirdness that I think has to do with this namespace.

Before I get started, I want to describe how I set up the library. First I invoked npm like so to install:

npm install --save jszip
npm install --save @types/jszip

Then I set up my tsconfig.json to include this:

var map = {
    'jszip':                      'node_modules/jszip/dist/jszip.min.js'
};

I'm not sure that step matters but it might allow calling the import "jszip" down below.

Then I tried a few import commands in the code, but was hit with errors. First I tried:

import * as JSZip from 'jszip';

namespace program {
    ...
}

But this causes a large count of errors within that file. I get "namespace is declared but never used" warnings for that large namespace, at least within the file I am performing the import call in. Every reference to an external file within that namespace is also broken, and for those I get a "Cannot find name '...'" error. So calling the import like that seems to be incompatible with the use of a namespace.

So then I tried:

namespace program {
    import * as JSZip from 'jszip';

    ...
}

So, in this case I at least do not get file-wide errors, but that line is still creating errors. The two I get are "Import declarations in a namespace cannot reference a module." and "Cannot find module 'jszip'" (notably, I do not get the latter error when using the previous method.)

So this makes me think something is wrong in my approach or setup, but even though I am stuck at a relatively simple point I have not been able to find a resource yet to help understand the exact issue. Of course I found some resources that I've cobbled together a limited understanding with at least though, links here:

types/jszip: https://www.npmjs.com/package/@types/jszip

jszip: https://www.npmjs.com/package/jszip

This is a close example but not identical to my case. I don't think the solutions proposed will work in my situation, but I could be wrong: How to use namespaces with import in TypeScript

This is where I got the clue for the "import * ..." syntax and adding the "map" property to tsconfig: Import JSZip in Angular 2 project

Upvotes: 2

Views: 1329

Answers (1)

Paleo
Paleo

Reputation: 23762

How to use JSZip in an old-fashion ambient project with concatenated JavaScript files

From the official documentation, JSZip can be installed manually:

Manually : download JSZip and include the file dist/jszip.js or dist/jszip.min.js

For TypeScript, the easiest way is without typings. Create a new file with this content:

// global-defs.d.ts
declare const JSZip: any;

Or, you can try to import typings manually. Create a file jszip.d.ts and paste all the content of its typings. Now, remove the last line export = JSZip;. Your file ends with:

declare var JSZip: JSZip;

Then, the code from the package documentation should works.

The classic solution for a brand new project

In a clean directory:

npm init
npm install --save jszip
npm install -D @types/jszip typescript

Then, create a valid tsconfig.json file. For example:

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
  },
  "exclude": [
    "node_modules"
  ]
}

Create a source file:

// main.ts
import JSZip = require('jszip');

// Here, use the code from the package documentation
// here: https://www.npmjs.com/package/jszip

Some advice:

  • Do not use import * as JSZip for something that is not a module namespace object. You should use import JSZip = require(…) in your case.
  • Do not use TypeScript namespaces and ES6 modules together. Your code imports a module, so just remove your namespace program.

More documentation on ES6 modules (including module namespace objects) here.

Upvotes: 1

Related Questions