Reputation: 31739
I read how TypeScript module resolution works.
I have the following repository: @ts-stack/di. After compiling the directory structure is as follows:
├── dist
│ ├── annotations.d.ts
│ ├── annotations.js
│ ├── index.d.ts
│ ├── index.js
│ ├── injector.d.ts
│ ├── injector.js
│ ├── profiler.d.ts
│ ├── profiler.js
│ ├── providers.d.ts
│ ├── providers.js
│ ├── util.d.ts
│ └── util.js
├── LICENSE
├── package.json
├── README.md
├── src
│ ├── annotations.ts
│ ├── index.ts
│ ├── injector.ts
│ ├── profiler.ts
│ ├── providers.ts
│ └── util.ts
└── tsconfig.json
In my package.json I wrote "main": "dist/index.js"
.
In Node.js everything works fine, but TypeScript:
import {Injector} from '@ts-stack/di';
Could not find a declaration file for module '@ts-stack/di'. '/path/to/node_modules/@ts-stack/di/dist/index.js' implicitly has an 'any' type.
And yet, if I import as follows, then everything works:
import {Injector} from '/path/to/node_modules/@ts-stack/di/dist/index.js';
What am I doing wrong?
Upvotes: 1112
Views: 1818887
Reputation: 31739
Here is other solution
When a module is not yours - try to install types from @types
:
npm install -D @types/module-name
Upvotes: 1078
Reputation: 2589
For anyone else reading this, try renaming your .js file to .ts
Edit:
You can also add "allowJs": false
to your tsconfig file.
Upvotes: 114
Reputation: 3179
For me, when I switch to my laptop and making sure I git fetch
and git pull
and npm install
, one of the packages (namely, ts-pattern
) has caused this error.
The way I've solved this is to do npm clean-install
. I think there was a problem with package-lock.json
or something.
Upvotes: 1
Reputation: 18281
The problem is that you have typescript configured with "old" moduleResolution
. If you edit tsconfig.json
to have moduleResolution: "nodenext"
, it will correctly find the types from the package.json
definitions.
Unfortunately, that will probably cause a lot of headache in your current repo.
Therefore you can use this workaround:
Add a re-exporting .ts
file for every entry that isn't in the exact path that TS thinks it is.
So in your case, you would add /index.ts
to your package (yes, with the .ts
extension, do not convert to .js
), and it should contain simply
// Stub to make TS happy. Do not add an extension to the import!
export * from "./dist"
The path you're re-exporting should not have extensions, so that TS will try resolving it and will find the index.d.ts
types file that's connected to it. If your types file is not named in a way that TS will find it when importing from the javascript, you have to rename it.
If you are creating a package with exports, the same thing applies. Suppose you have an export /vite
which loads from /dist/vite.mjs
, you have to add the file /vite/index.ts
which does export * from "../dist/vite"
. Only TS will read this file.
Upvotes: 4
Reputation: 169
Just add // @ts-ignore
before import like that:
// @ts-ignore
import replace from 'replace'
Upvotes: -2
Reputation: 31739
If you're using a third party package, see my answer below.
Remove .js
from "main": "dist/index.js"
in package.json
.
"main": "dist/index",
Also add types
in package.json
per the TypeScript docs:
"main": "dist/index",
"types": "dist/index",
The folder dist
is where the TS compiler stores your module's files.
Upvotes: 215
Reputation: 29
What works for me is installed the dependencies as dev dependencies. Above solution of disabling implicit type checking works but that kept me away from getting advantage of strictly typed code. So what you have to do is to just append the all the @types module installation with --save-dev flag.
Upvotes: 1
Reputation: 37
You may need create the file with .d.ts
extension.
push this file name under include
key of tsconfig.json
file:
"include": [
"src",
"index.d.ts"
]
Upvotes: 2
Reputation: 5092
In my case, adding paths alias worked and typescript found the declaration file:
// tsconfig.json
{
"compilerOptions": {
...
paths: {
"*": ["@types/*"]
}
}
}
And then add declaration files you need to @types/ folder:
declare module 'not-found-module' {
// your declations
}
Upvotes: 2
Reputation: 1383
Nobody mentioned here, but my solution was a simple restart in the last time I encountered this problem.
npm start
and it started working.Upvotes: -2
Reputation: 2264
just run this command and will solve the problem
npm install --save @types/node-forge
more info in the next link
https://www.npmjs.com/package/@types/node-forge
Upvotes: 1
Reputation: 465
I had the same problem with uuid module in angular project.
Definitely not for prod, but putting '// @ts-ignore' on the previous line has quickly "solved" my problem.
Upvotes: -2
Reputation: 524
In my case, 3 different ways of resolving this issue are all not working. Once you set "type" as "module" in package.json then it will comply with ES Module instead of CommonJS syntax. I was able to resolve this by using ES Module syntax according to my package.json settings.
import ws from 'ws'
export const create = (/** @type {string} */ accessToken) => {
const WebSocket = ws;
return new WebSocket(endpoint, accessToken, sslOptions);
}
This way you are able to use the WebSocket class in 'ws' module. It's an example of a node module but you can basically put any type of node module and the functions in it.
Those are NOT working for me below:
npm install -D @types/module-name
const foo = require('module-name');
// index.d.ts
declare module 'foo';
"noImplicitAny": true,
"allowJs": true
Upvotes: 5
Reputation: 563
In most cases you would likely install a types package for your dependency, either way you could add allowJs -> true in your tsconfig.json file
Upvotes: 6
Reputation: 4954
This worked for me.
// modules.d.ts
declare module 'my-module';
// tsconfig.json
{
...
"include": [
...
"src", "modules.d.ts"
]
}
// Import
import * as MyModule from 'my-module'
...
const theModule = MyModule()
...
Upvotes: 21
Reputation: 23
for people who are getting this error in React, in tsconfig.json, set
"compilerOptions" : {
...
"strict": false,
...
}
the auto-generated config from React's create-react-app has that flag set to true
Upvotes: -3
Reputation: 2381
Building on Retsam's answer, you can also use wildcards (*
) in yourDeclarations.d.ts
file. For example, if you're trying to import a file, such as a .css
or .webp
file, you can place a *
at the beginning of the file type declaration. It'd look something like this ⤵︎
declare module '*.webp';
Now you can import all the .webp
files you'd like without any linting errors.
Upvotes: 2
Reputation: 710
This way works for me:
declare module 'Injector';
{
"compilerOptions": {
"strictNullChecks": true,
"moduleResolution": "node",
"jsx": "react",
"noUnusedParameters": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports":true,
"target": "es5",
"module": "ES2015",
"declaration": true,
"outDir": "./lib",
"noImplicitAny": true,
"importHelpers": true
},
"include": [
"src/**/*",
"index.d.ts", // declaration file path
],
"compileOnSave": false
}
Upvotes: 58
Reputation: 1196
Just create a file named typings.d.ts
in the root directory of your project.
Inside this file just add declare module <module_name>
. Here, module_name
can be any module's name that you want to import. Finally, open the tsconfig.json
file and include the file typings.d.ts
inside the array named as include array
.
// typings.d.ts
declare module 'abc-module';
// tsconfig.json
{
...
"include": [
"src", "typings.d.ts"
]
}
// BOOM, Problem solved!!!
This technique provides your module with a type named "any". For more info: https://medium.com/@steveruiz/using-a-javascript-library-without-type-declarations-in-a-typescript-project-3643490015f3
Upvotes: 29
Reputation: 2700
From the Typescript documentation:
Note that the "typings" field is synonymous with "types", and could be used as well.
Also note that if your main declaration file is named index.d.ts and lives at the root of the package (next to index.js) you do not need to mark the types property, though it is advisable to do so.
For some reason my "types" property was pointing to some main.d.ts. Removed the line from the package.json and it started working.
Upvotes: 0
Reputation: 25
import { io, Socket,SocketIOClient } from 'socket.io-client';
Adding this on top of component.ts worked in my case.
Upvotes: -9
Reputation: 113
I was facing the same problem with many packages in many projects. So i created Declarator, a npm package that generate type declarations automatically.
It basically works by running tsc --emitDeclarationOnly
in the background.
You can install it from npm:
npm install --save-dev declarator
yarn add -D declarator
Then create a simple declarator.json
file:
{
"$schema": "https://raw.githubusercontent.com/ArthurFiorette/declarator/master/schema.json",
"packages": ["package1","package2"]
}
And create a script to run it:
Using postinstall script will run it on every package installation, may be useful
{
"scripts": {
"postinstall": "declarator"
}
}
It won't generate powerful types and you'll probably encounter many any
types along the way, but it's much better with than without
Read more: https://github.com/ArthurFiorette/declarator#readme
Upvotes: 4
Reputation: 143
All you have to do is edit your TypeScript Config file (tsconfig.json) and add a new key-value pair as "noImplicitAny": false
Upvotes: -4
Reputation: 4849
create the file with an arbitrary name and .d.ts
extension.
ex: index.d.ts
push this file name under include
key of tsconfig.json
file:
"include": [
"src",
"index.d.ts"
]
Upvotes: 0
Reputation: 70126
The answers from @ktretyak and @Retsam are correct but I would like to add a complete real time example and what I had to do:
Error:
Error TS7016 (TS) Could not find a declaration file for module 'react-region-select'.
'C:/Repo/node_modules/react-region-select/lib/RegionSelect.js' implicitly has an 'any' type.
Try
npm i --save-dev @types/react-region-select
if it exists or add a new declaration (.d.ts) file containing `declare module
Running npm i --save-dev @types/react-region-select
gives the error:
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@types%2freact-region-select - Not found
npm ERR! 404 '@types/react-region-select@latest' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404 Note that you can also install from a npm tarball, folder, http url, or git url.
Given that create-react-app
creates a file called react-app-env.d.ts
I tried to put declare module 'react-region-select';
in there but I still received the error.
I then created a new folder in src
called typings
and a file called react-region-select.d.ts
. In there I declared the module like this:
declare module 'react-region-select';
After doing it like this the error disappeared and I could import it like the documentation states:
import RegionSelect from "react-region-select";
https://github.com/casavi/react-region-select
Upvotes: 5
Reputation: 5011
Unfortunately it's out of our hands whether the package writer bothers with a declaration file. What I tend to do is have a file such index.d.ts
that'll contain all the missing declaration files from various packages:
Index.d.ts:
declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';
and reference it to in your tsconfig.js
:
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx",
"index.d.ts" // this
]
Upvotes: 39
Reputation: 1245
A simple fix:
// example.d.ts
declare module 'foo';
If you want to declare an interface of an object (Recommended for big projects) you may use :
// example.d.ts
declare module 'foo'{
// example
export function getName(): string
}
How to use that? simple..
const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this
Upvotes: 6
Reputation: 4677
If you are seeing this error in Webstorm, and you just installed the package, you might need to restart the typescript service before it will pick it up.
Restart Typescript Service
Upvotes: 3
Reputation: 656
Solution: All you have to do is edit your TypeScript Config file tsconfig.json
and add a new key-value pair as
"compilerOptions": {
"noImplicitAny": false
}
Upvotes: 9
Reputation: 503
If import is not working for you
import * as html2pdf from 'html2pdf.js';
Comment the code, keep the below script file in index.html as given in the official docs.
<script src="https://rawgit.com/eKoopmans/html2pdf/master/dist/html2pdf.bundle.min.js"></script>
And declare the html2pdf variable in the component you are using it.
declare var html2pdf: any;
That's it. I was stuck in this issue for 2 days, but finally got it resolved.
Upvotes: 0