Reputation: 461
Over the past few days I have been trying to create a .d.ts for a simple library I found on npm and used in an angular 4 project (creating typescript .d.ts for third-party library). I was able to create such a declaration file, and I thought that the other problem I had, moving the declaration file to a more appropriate directory, would be fairly simple.
While working on the original problem I had simply created the .d.ts declarations file under <root>/node_modules/@types
along with the type delcaration files I had downloaded and not created. I had done this because it was fairly clear that my attempts to put the declarations file in another directory were not working, and that seemed a secondary problem. Once I had solved the primary issue I addressed the secondary. I could not find anything to add locations to search for declaration files. I found a setting in tsconfig.json
that sounded promising,
"typeRoots": [
"node_modules/@types",
"hmm/@types"
],
here with an experimental value, but the value did not do what it sounded like it ought to do. In fact I could remove all the values in the list and not get any different behavior, including for other type libraries. (I have since found a mention that it is used only to resolve directories for /// <reference=...
directives.)
After a great deal of experimentation and some scanning of the tsc
code, I stumbled into the realization that if the directory containing additional typescript declarations files included node_modules/@types
. tsc would find them and treat them as declaration files. In addition to <root>/npm_modules/@types
I created <root>/src/npm_modules/@types
, and everything worked as expected. I wasn't happy with the directory name so I tried <root>/src/@types/npm_modules/@types
, but that failed.
All my builds were through angular-cli ng
, so it's possible ng
is secretly creating configuration files that it uses instead of the ones I see, but I don't think that is the case.
Is there any way to configure additional type declaration files for tsc, or to get tsc to recognize certain directories as such? There is a "types" parameter on tsconfig.json, but that seems to mean use only those type files, and I would like to use some type files additionally. Ideally I think I would like a directory structure similar to: <root>/@types/library-package-name
. Is this possible?
Upvotes: 4
Views: 4023
Reputation: 461
After some more research and reflection, I believe that putting the ambient declaration file for a third-party library can only be done by putting the file in a directory named "node_modules/@types/ somewhere either off the directory where the third-party library is being used, or off one of its parent directories. If, using an angular 5 example, the component SimpleComponent (in src/app/simple/simple.component.ts) imported a library 'chi-squared-test', the ambient declarations file, chi-squared-test/index.d.ts, could be put in: node_modules/@types/chi-squared-test/index.d.ts (with the installed ones), in src/node_modules/@types/chi-squared-test/index.d.ts, in src/app/node_modules/@types/chi-squared-test/index.d.ts or in src/app/simple/node_modules/@types/chi-squared-test/index.d.ts. I have verified that src/node_modules/@types works. The documentation from typescript here says that the others ought to work too, but I have not tested them.
I have seen posts that suggest to me that one ought to be able to put declaration files not in directories that include "node_modules/@types" by using the "typeRoots" configuration value but I was never able to get that to work. At this point the only way I know which will add ambient type declaration files (.d.ts) is to put them in subdirectories named "node_modules/@types" on the path from directory containing the file that needs the declaration to the project root.
This may be require some work with your .gitignore file. By default I believe it ignores subdirectories that have "node_modules" in the path. In most cases I expect you will want to commit your private library declarations to git, so you will have to adjust your .gitignore to include those directories (a line like "!src/node_modules" should work).
Upvotes: 1