Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import modules with ‘Typings’ in TypeScript without <reference>?

I`m trying to write tests with Protractor and Jasmine in TypeScript. TSD is now deprecated so I have to use 'Typings' to manipulate TypeScript definitions. So I installed it:

npm install typings -g

Then I used it to install Jasmine and Chance definitions like that:

typings install jasmine --source dt --save –-global
typings install chance--source dt --save –-global

And I also added “files” section and excluded 'node_modules':

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "declaration": false,
    "noImplicitAny": false,
    "outDir": "tmp",
    "types": ["node", "jasmine", "chance"]
  },
  "files": [
    "typings/index.d.ts"
  ],
  "include": [
    "lib",
    "specs"
  ],
  "exclude": [
    "node_modules"
  ]
}

The problem is neither WebStorm nor Visual Code studio can`t find definitions for all Jasmine methods and 'chance' module. Errors are:

**“TS2304: Cannot find name 'describe'”** 
**“TS2307: Cannot find module 'chance'”**

respectively. Here is my spec file:

enter image description here

In 'typings/' folder I see reference links to TypeScript definitions:

folders structure and typings/index.d.ts content

Am I missing something? Why my IDE can`t find definitions for Jasmine and Chance?

P.S. Test works after transpiling to Javacript.

P.S.S. Errors will disappear after adding

///<reference path="###"/>

to the spec file. But I don`t want to use it.

Protractor: 4.0.9;
TypeScript 2.0.3;
Typings 1.5.0;

Thanks in advance!

like image 462
oliverfrost21 Avatar asked Oct 30 '16 20:10

oliverfrost21


People also ask

When using TypeScript where should you import modules from?

Use import myFunction from "./myModule" to bring it in. More commonly, TypeScript modules say export myFunction in which case myFunction will be one of the properties on the exported object. Use import { myFunction } from "./myModule" to bring it in.

Which is the default module format used while compiling modules in TypeScript?

By default, files in TypeScript are treated as global scripts. This means that any variable, class, function, or other construct declared in the file is available globally. As soon as you start using modules in a file, this file becomes module-scoped, and is no longer executed globally.

Can't find module or its corresponding type declarations?

The "Cannot find module or its corresponding type declarations" error occurs when TypeScript cannot locate a third-party or local module in our project. To solve the error, make sure to install the module and try setting moduleResolution to node in your tsconfig. json file.


2 Answers

There's a few things that are preventing things from working well for you. First of all, if you are using Typescript 2.0 then typings is also sort of deprecated.

Typescript 2.0 supports packaging typings in node modules (usually installed by npm install @types/module-name. All declarations available on definitely typed are also available as npm modules under the "@types/*" namespace, so if you are looking to move away from tsd, typings should not be your final destination.

That being said, typescript 2.0 will still work with typings so let me point a few of the issues I see in your config file.

Types Property

{ 
    "types": ["node", "jasmine", "chance"]  
}

The types, property is meant to only be used with the new npm package-based typings in @types/*. Since you are not using this yet, you should not have this property in your tsconfig.json. (See TypeScript 2: custom typings for untyped npm module for a full discussion of what this and related properties do.

Files/Include/exclude properties

{
 "files": [
    "typings/index.d.ts"
  ],
  "include": [
    "lib",
    "specs"
  ],
  "exclude": [
    "node_modules"
  ]
}

While you can chose to use both files and include properties at the same time, this is not necessary. You can move your typings/index.d.ts reference from the files array and into the include array and then just eliminate files.

Also, the big problem you have is that your include syntax is wrong. include takes glob patterns. You cannot just simply put folder names, but need to follow them by a recursive pattern:

{
  "include": [
    "typings/index.d.ts",
    "lib/**/*",
    "specs/**/*"
  ],
}

The last thing is that you do not need to exclude node_modules. Exclude is only necessary to exclude things that would otherwise match your include patterns. Since node_modules would not be matched by your include patterns, there is no need to exclude it.

I think if you make these small changes things should work as you expect, but again, I would really look into going all the way and migrating to the new @types/* based typings, as they are much easier to manage and more convenient and do not require an external tool (other than npm) like typings or tsd.

like image 166
Daniel Tabuenca Avatar answered Sep 22 '22 12:09

Daniel Tabuenca


You need to update your compilerOptions as follows:

  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "declaration": false,
    "noImplicitAny": false,
    "outDir": "tmp",
    "typeRoots": ["./typings"] // Updated!
  },

typeRoots automatically includes all definition files under the specified folder(s) in your compilation without the need to add a references directive to the relevant files, or the need to create an index file (which you then need to update whenever you add a new ambient library).

Your current configuration ("types": ["node", "jasmine", "chance"]) will only search for definition files in node_modules/@types, and then only include the node, jasmine, and chance definitions.

This is explained in detail in the tsconfig.json documentation.

EDIT: You're using a JetBrains IDE. If the IDE is compiling the JS for you, make sure it's using your tsconfig.json for settings instead of its own. It's in the preferences.

like image 27
Rich Seviora Avatar answered Sep 22 '22 12:09

Rich Seviora