Typescript: `typeRoots` is not resolved as part of compilation

Created on 11 Sep 2018  ·  9Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 3.0.1 and 3.1.0-dev.20180907
(Windows 7, everything on local C:\ drive)

I can't make typeRoots to work at all. There is a lot of similar complaints over Stackoverflow and elsewhere, but I don't see a single complete workable example. So here's a simplest reproduction case. It doesn't work for me.

In summary, I install three.js from NPM into node_modules, but want to use typings from local directory. For simplicity those are exact same types you get from @types/three — without any modifications.

Code

Project structure:

node_modules
   three  <------------ installed as usual with  "npm install three"
src
   package
      three   <------------ exact copy of typings for three.js
      webvr-api

useThree.ts
tsconfig.json

useThree.ts:

import * as THREE from "three";

function main(s: THREE.AmbientLight) {
}

tsconfig.json
```tsconfig.json
{
"compilerOptions": {
"typeRoots" : ["./src/package"],
"strict" : true
}
}


Trying to compile with:

tsc.cmd -p tsconfig.json


**Expected behavior:**
Compile successfully. Also show suggestions when you type `THREE.` in VSCode.

**Actual behavior:**
Compiler doesn't understand `typeRoots` at all.

error TS2688: Cannot find type definition file for 'three'.
`` Also VSCode treatsTHREEasanyand doesn't offer suggestions likeAmbientLight` and others.

As I said, several of confused questions on Stackoverflow, with general answer reciting scarce TypeScript/tsconfig docs on the typeRoots:

If typeRoots is specified, only packages under typeRoots will be included. For example:
{ "compilerOptions": { "typeRoots" : ["./typings"] } }

You can see, I used the same syntax, to the point of leading ./ and lack of trailing /.

Quite possibly some other intricate (or obvious??) detail is missed on my part. In that case what would help A LOT is one small thing: a simple reproduction example where typeRoots works as expected.

I can see there are couple dozen tests exercising @typeRoots with harness virtualized file system, but would be good to have it clean and reproduceable with just tsc. Thanks!

Question

Most helpful comment

  1. FBOFW, baseUrl is required when paths is specified.
  2. The key should be "three" because that's what's being imported. It's a good enough overview for present purposes that when you import ... from "foo", TypeScript checks for a declaration file in (a) any specified paths for foo, (b) node_modules/foo, and (c) node_modules/@types/foo in that order. Given that you can never import ... from "@types/foo", a paths setting for @types/foo will never be used.

So the tsconfig.json in your example would be:

{
   "compilerOptions": {
       "lib": ["es6", "dom"],
       "baseUrl": ".",
       "paths": {
         "three": ["customtypings/node_modules/@types/three"]
       },
       "strict" : true
   }
}

All 9 comments

I can't reproduce the problem. Use the --traceResolution flag to get more information, and if you still can't fix the problem, please ask on Stack Overflow and we can troubleshoot there.

We'd need at minimum a sample repo for this, since we can't see what the filenames are, what the file contents are, whether there are package.json files, etc.

I've created a trivial reproduction repository:

https://github.com/mihailik/typeRoots

  • git clone https://github.com/mihailik/typeRoots
  • npm install (getting typescript, three and @types/three packages in respective places)

    • typescript and three go in normal place

    • @types/three intentionally goes in a nested subdirectory — precisely the use case for typeRoots

  • npm run build to fire tsc with tsconfig

I've reproduced it on:

Should be pretty easy to check and hope you can point out the issue easily.

If it's a misconfiguration on my side, it would be awesome to have a similarly trivial sample case, but working. The typeRoots official docs are vague, no sample either. Let's help people use typeRoots correctly!

Thanks @RyanCavanaugh @mattmccutchen

@mihailik You should be using baseUrl/paths, not typeRoots, in this case. See this Stack Overflow answer.

This seems to be a very common misconception and we should see if we can improve the documentation.

Thanks @mattmccutchen — follow-ups:

  1. Do we need to include "baseUrl": "." or can it be omitted as default?
  2. What would be the actual syntax for "path" in my case above? I'm confused whether to refer to "three" or "@types/three".

With that I can update the repo, and make it a definite working sample for other people to look at.
Thanks!

  1. FBOFW, baseUrl is required when paths is specified.
  2. The key should be "three" because that's what's being imported. It's a good enough overview for present purposes that when you import ... from "foo", TypeScript checks for a declaration file in (a) any specified paths for foo, (b) node_modules/foo, and (c) node_modules/@types/foo in that order. Given that you can never import ... from "@types/foo", a paths setting for @types/foo will never be used.

So the tsconfig.json in your example would be:

{
   "compilerOptions": {
       "lib": ["es6", "dom"],
       "baseUrl": ".",
       "paths": {
         "three": ["customtypings/node_modules/@types/three"]
       },
       "strict" : true
   }
}

@mihailik Did you get it working?

Yes, I did @darkmastermindz — following @mattmccutchen example.

Thanks a lot, by the way! 👍

Could be super-useful to put in docs too!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antony-Jones picture Antony-Jones  ·  3Comments

weswigham picture weswigham  ·  3Comments

MartynasZilinskas picture MartynasZilinskas  ·  3Comments

wmaurer picture wmaurer  ·  3Comments

blendsdk picture blendsdk  ·  3Comments