Typescript: typeRoots is not finding custom declaration file

Created on 28 Feb 2018  ·  15Comments  ·  Source: microsoft/TypeScript



TypeScript Version:
Version 2.6.2


Search Terms:
declaration file for module exporting function, external module, npm package, third-party module

Code
src/testFile.ts:

import getFieldList = require('graphql-list-fields');

src/@types/graphql-list-fields/index.d.ts:

// Doing just this below (as suggested by the Typescript Handbook does not work 
// and results in the tsc error under **Actual behavior** below
import { GraphQLResolveInfo } from 'graphql';
declare function getFieldList(info: GraphQLResolveInfo): string[];
export = getFieldList;

// The code below is what actually works instead of the above
/*
declare module 'graphql-list-fields' {
    import { GraphQLResolveInfo } from 'graphql';
    function getFieldList(info: GraphQLResolveInfo): string[];
    export = getFieldList;
}
*/

Expected behavior:
Compiling without errors.

Actual behavior:
Error when running tsc:

src/testFile.ts(1,31): error TS7016: Could not find a declaration file for module 'graphql-list-fields'. '/node_modules/graphql-list-fields/index.js' implicitly has an 'any' type.
Try `npm install @types/graphql-list-fields` if it exists or add a new declaration (.d.ts) file containing `declare module 'graphql-list-fields';`

graphql-list-fields is an NPM package that I'm trying to use, which currently has no published type declarations.

After reading through the Typescript Handbook's section on declaration files, I found that I am trying to write a declaration file for a modular library and should use the module-function.d.ts declaration file template. This is how I came up with the code in index.d.ts above, but the compiler still complains about not having the declaration file for the module 'graphql-list-fields'. After trial and error, we found that adding declare module 'graphql-list-fields' around everything worked without compiler errors.

We tried setting "typeRoots": ["./node_modules/@types", "./src/@types"] in tsconfig.json, as mentioned in the tsconfig docs but that still did not work without declare module 'graphql-list-fields'. This seems to be an issue because tsc is not finding the type declaration in the directories specified in typeRoots.

Related Issues:
3019, 8335

Question

Most helpful comment

TypeRoots is really a support we have added for back compat with typings and to allow migration, so we tried to keep it out of the docs as much as possible to avoid confusion.

@mhegazy Having a supported feature with little-to-no documentation is what drives confusion. Please properly document features like this but be liberal with your warning language. For example:

_Note: This feature is provided for backwards compatibility with typings to support migration. See the release notes [here] for more information._

This would be _vastly_ preferable to having to scan GitHub Issues, StackExchange, etc. for information.

All 15 comments

"typeRoots" is meant for global code. i.e. something that is declarated in the global namespace, and you want to include it. this is why your declare module 'graphql-list-fields' {.. works, since it just declares a module with that name in the global namespace.

For modules, they have thier own scope, all you need is path mappig..

somethign like:

{
    "compilerOptions": {
        "target": "es5",
        "baseUrl": "./",
        "paths": {
            "*" : ["src/@t`ypes/*"]
        }
    }
}`

Thanks for clearing that up @mhegazy. I think it would be helpful if this was explained more in the TypeScript docs, possibly under the declaration files section.

TypeRoots is really a support we have added for back compat with typings and to allow migration, so we tried to keep it out of the docs as much as possible to avoid confusion.

Not sure if this fits in the declaration file section. we do have a note about it in https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping

I can add a note in the declaration file section about module resolution section as a whole.

give that section a read and let us know if you still find docs in it lacking

Oh I see. Yeah, that is the page that I needed to begin with. I think it would be nice to have at least a brief mention of path mapping and maybe a link to that doc somewhere under https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

I still think it would be helpful to have the docs updated as stated in my previous comment @typescript-bot

TypeRoots is really a support we have added for back compat with typings and to allow migration, so we tried to keep it out of the docs as much as possible to avoid confusion.

@mhegazy Having a supported feature with little-to-no documentation is what drives confusion. Please properly document features like this but be liberal with your warning language. For example:

_Note: This feature is provided for backwards compatibility with typings to support migration. See the release notes [here] for more information._

This would be _vastly_ preferable to having to scan GitHub Issues, StackExchange, etc. for information.

Thx a fucking ton @mhegazy ! :tada: That path entry for @types was finally the missing piece which made my non-standard project setup work. I spent days on this.

If you don't mind slow down your application starting process little, you can just add TS_NODE_FILES=true to your package.json's start script and all custom declaration file will be found.

I'm now getting:

The following changes are being made to your tsconfig.json file:
  - compilerOptions.paths must not be set (aliased imports are not supported)

and this option is being deleted.

@KrzysztofMadejski that's done by CRA, not TS itself.

This thread says that typeroots is really for backwards compatibility. I am trying to use it to author types for definitively typed. How else would I properly test these types without typeroots? I have generated types using dts-gen and added types to my type roots and still no luck :-(

@Roaders did you find the solution to use dts-gen generated types?

Edit: Solved with https://github.com/microsoft/TypeScript/issues/22217#issuecomment-369783776

One thing I don't understand here is that:

tsconfig.base.json:

"typeRoots": ["node_modules/@types", "types"],

And a directory structure:

/node_modules/@types/something/index.d.ts
/types/something-else/index.d.ts

It won't get picked up at all in my nrwl/nx repository. I can try a million things but if I move that something-else folder into node_modules/@types it'll magically work and get picked up, which suggests the typeRoots does absolutely nothing as node_modules/@types is magically handled.

Marking typeRoots as deprecated and saying it works in a weird/quirky way would have at least stopped me trying to use it.

The only way I've managed to add local types each time I've needed to, is by spending hours fighting with my tsconfig.base.json and stumbling upon the mhegazy comment above

I kept getting bitten by this and forgetting about having to configure the paths option as well, so I created a simple repository with the proper settings. Hope it helps someone.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fwanicka picture fwanicka  ·  3Comments

wmaurer picture wmaurer  ·  3Comments

manekinekko picture manekinekko  ·  3Comments

Zlatkovsky picture Zlatkovsky  ·  3Comments

Antony-Jones picture Antony-Jones  ·  3Comments