Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when importing untyped JS modules #15031

Closed
balajikris opened this issue Apr 5, 2017 · 46 comments
Closed

Error when importing untyped JS modules #15031

balajikris opened this issue Apr 5, 2017 · 46 comments
Labels
Fixed A PR has been merged for this issue

Comments

@balajikris
Copy link

balajikris commented Apr 5, 2017

TypeScript Version: 2.2.1

Steps

  1. In a simple TS project in VSCode, add "adal-node": "^0.1.22", to package.json and run npm install. This is a JS library with no types.
  2. Import the library in your index.ts as below

Code

import adal from "adal-node";

Expected behavior:
Per this bug's resolution #3019 this code should compile with no errors

Actual behavior:
tsc.exe: 'Could not find a declaration file for module 'adal-node'. 'e:/proj/node_modules/adal-node/lib/adal.js' implicitly has an 'any' type.'

References:
see #3019 and all its linked bugs

@balajikris
Copy link
Author

/cc: @mhegazy

@unional
Copy link
Contributor

unional commented Apr 5, 2017

Because you have turned on noImplicitAny. You need to get around it by doing declare module 'adal-node' (or declare module "*", I have yet to try this myself)

@unional
Copy link
Contributor

unional commented Apr 5, 2017

#13348

@balajikris
Copy link
Author

oops! you're right that I have noImplicitAny compiler option set in my tsconfig.json. Totally forgot about it as its one of my default configs to writing TS.

I think I can work with the solution you posted on the other thread. Thanks for the quick feedback ! Appreciate it.

@balajikris balajikris reopened this Apr 5, 2017
@balajikris
Copy link
Author

balajikris commented Apr 5, 2017

I tried the suggestions mentioned in the linked bug like so:

In index.ts i added this code:

declare module 'adal-node/*'{
    var _a: any;
    export = _a;
}

and i get this error:
tsc.exe : Invalid module in augmentation, module 'adal-node/*' cannot be found. Can someone help me how to do this correctly?

@masaeedu
Copy link
Contributor

masaeedu commented Apr 5, 2017

@balajikris Have you tried:

declare module 'adal-node' {
    var _a: any;
    export = any;
}

instead?

@balajikris
Copy link
Author

balajikris commented Apr 5, 2017

@masaeedu : Thanks for the comment. Yes, I did try that earlier. It also errored out, but a slightly different message.

tsc: 'Invalid module name in augmentation. Module 'adal-node' resolves to an untyped module at 'e:/proj/node_modules/adal-node/lib/adal.js', which cannot be augmented.'

@billti
Copy link
Member

billti commented Apr 5, 2017

So it's loading the module via the .js file also it seems. Do you have 'allowJs' set in your project config?

@balajikris
Copy link
Author

@billti : Thank you for the hint. I tried after setting allowJs: true and the error message remains the same as above.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Apr 6, 2017

declare module 'adal-node/*'{
    var _a: any;
    export = any;
}

did you mean

declare module 'adal-node/*'{
    var _a: any;
    export = _a;
}

?

@balajikris
Copy link
Author

@aluanhaddad -- yes ofcourse. sorry, that was a typo! updated my post

@TAGC
Copy link

TAGC commented Apr 13, 2017

Is there any way to do something simple like import * as BabiliPlugin from "babili-webpack-plugin"; with noImplicitAny enabled without getting warning TS7016 ("could not find a declaration file...implicitly has an 'any' type")?

@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2017

Is there any way to do something simple like import * as BabiliPlugin from "babili-webpack-plugin"; with noImplicitAny enabled without getting warning TS7016 ("could not find a declaration file...implicitly has an 'any' type")?

Add a declaration for your module, e.g.:

declare module "babili-webpack-plugin" {
     export ...
}

or simply:

declare module "babili-webpack-plugin";

@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2017

The issue as described by the OP seems fixed.

The other issue described in #15031 (comment), is because a module declaration (i.e declare module 'adal-node' {... }) inside another module (i.e. a file with at least one top-level import or export) is considered an "augmentation".
What you want is to move this declaration to a global .d.ts (as you want it to be in the global scope) file instead of keeping it in your module.

@mhegazy mhegazy closed this as completed Apr 19, 2017
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Apr 19, 2017
@balajikris
Copy link
Author

@mhegazy : I'm still not sure how to correctly use this declare module and import syntax to import untyped JS modules. Could you please provide a small snippet demonstrating how to accomplish that? Thanks.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2017

c:\test\15031>npm install adal-node
npm WARN deprecated node-uuid@1.4.7: Use uuid module instead
test@1.0.0 c:\test\15031
`-- adal-node@0.1.22

c:\test\15031>echo import adal from "adal-node"; > a.ts

c:\test\15031>type a.ts
import adal from "adal-node";

c:\test\15031>tsc a.ts

@balajikris
Copy link
Author

Interesting, so i do not have to do a declare xxx and a simple import adal from "adal-node"; as in my original bug report should work.

I'm on tsc v2.2.2 and I'm seeing error TS1192: Module ''adal-node'' has no default export. for the above usage. What version of tsc.exe is this supposed to work on?

@TAGC
Copy link

TAGC commented Apr 19, 2017

@balajikris I've just tried it using Typescript v2.2.2 and it works fine for me. Are you sure you're not picking up a stray tsconfig.json? Are you testing in the same directory?

@balajikris
Copy link
Author

Thanks for checking @TAGC . I do have a .tsconfig but that's intentional and not a stray one. I'll play with this a little more to understand what i'm missing.

@saschanaz
Copy link
Contributor

@balajikris probably import * as adal from "adal-node";?

@oreporan
Copy link

Still not being able to work with adal-node in typescript
I tried creating adal-node.d.ts:

declare module 'adal-node/*'{
    var _a: any;
    export = _a;
}

my import ts file still says:

error TS7016: Could not find a declaration file for module 'adal-node'. 'node_modules/adal-node/lib/adal.js' implicitly has an 'any' type.
  Try `npm install @types/adal-node` if it exists or add a new declaration (.d.ts) file containing `declare module 'adal-node';`

@mhegazy
Copy link
Contributor

mhegazy commented Sep 11, 2017

@oreporan i am unable to reproduce any errors for this scenario.

One note, if your import looks like import * as adal from "adal-node/argument"; then your module declaration looks correct, if it is however import * as adal from "adal-node"; then the module declaration does not match that. consider instead declaring it as declare module 'adal-node' { .. }

@oreporan
Copy link

Thanks
I ended up forking and making a pull request with typings and adding an index.js outside the lib, which solves the issues

@zbicin
Copy link

zbicin commented Jul 21, 2018

@slavafomin it worked for me in a similar case in another project, when I've put a new index.d.ts in the project root directory (i.e. in the same directory as the tsconfig.json is located).

@unional
Copy link
Contributor

unional commented Jul 21, 2018

You can put it anywhere as long as tsc can locate it. I.e. using files or include in tsconfig.json.

I put them under a custom-typings folder.

@SCLeoX
Copy link

SCLeoX commented Jul 23, 2018

@Spongman Actually, you can just have a global.d.ts at your project root with following content:

declare module '*';

It automatically makes all js modules any while ts modules keep working as intended.

@icfantv
Copy link

icfantv commented Jul 28, 2018

I can confirm @SCLeoX's suggestion. I just created a root-level global.d.ts file for untyped 3rd party libs. IMO, * is a bit too heavy-handed and I'd rather be explicit, so I simply took the module that the compiler was complaining about and declared it explicitly. But, that's just my opinion.

@nihildeb
Copy link

@SCLeoX OMG THANK YOU. Hours of pounding my head against outdated docs and absolutely terrible error messages from tsc. If this simple workaround was the front page of http://www.typescriptlang.org then typescript adoption would double and it would also be the most useful thing on that website.

@bitadj
Copy link

bitadj commented Sep 19, 2018

I've been hunting around for this answer for the better part of a month now. I found a solution that works in VS Code that isn't a wholesale disabling of all validation for javascript/typescript and also did not require that I add files/declarations to a repository that is not mine.

Add one or both of these lines to your user settings:

"typescript.suggestionActions.enabled": false,
"javascript.suggestionActions.enabled": false,

Unlike "javascript.validate.enable": false (which you should not use), the above setting will remove those annoying [ts] Could not find a declaration file for module errors for untyped module imports and it will still play nice with linters and give you appropriate and relevant errors.

@voidcenter
Copy link

In my case, the index.d.ts or global.d.ts got deleted every time I compile. Turn off noImplicitAny is the only solution works for me so far.

@gunar
Copy link

gunar commented Feb 1, 2019

I took @SCLeoX's suggestion and made the pattern-matching a bit narrower.

- declare module '*' {
+ declare module '*.js' {
   const value: any
   export default value
 }

@ackvf
Copy link

ackvf commented Feb 22, 2019

Is it possible to re-export an existing typed module and use its types for the untyped module?

I am importing a library react-final-form-html5-validation that is just a tiny wrapper around typed react-final-form.

Are there any options for this?

I have tried many many many things ......., but this looks most promising, however, react-final-form does not declare a namespace and so I cannot use its types like I can use the React below.

project/index.d.ts

/// <reference types="react-final-form" />
//// <reference types="./node_modules/react-final-form/dist/index.d.ts" />
//// <reference path="./node_modules/react-final-form/dist/index.d.ts" />
//// <amd-dependency path="./node_modules/react-final-form/dist/index.d.ts" />
// importing resolves the types, but also turns it into a module, which in turn breaks it
// import * as RFF from react-final-form; 
// import { FieldProps } from react-final-form;
// export * from react-final-form;

declare module 'react-final-form-html5-validation' {
  var Field: React.ComponentType<FieldProps>
}

project/src/index.tsx

import { Field, Abc } from 'react-final-form-html5-validation'
// correct: Module '"react-final-form-html5-validation"' has no exported member 'Abc'

// later in App.render() { return ( .....
      <Field />

// Field is of type React.ComponentType<any>

@P0oOOOo0YA
Copy link

Typescript should act smarter in these cases. WHY ON EARTH we need to define a type definition if we explicitly import a JS module.

@squarewave24
Copy link

i found this to be a helpful write up. https://medium.com/@chris_72272/migrating-to-typescript-write-a-declaration-file-for-a-third-party-npm-module-b1f75808ed2

in my case i just had to place the migration file in src/@types/@okta/library-name/index.d.ts and as long as the part after @types matched the import, it was picked up. inside can be just 1 line declaring the module

@rbrisita
Copy link

rbrisita commented May 17, 2019

Two year problem still plagues developers...

Below is an example using Angular and Laravel Mix (specific npm scripts) to help anyone else who faces this issue with an untyped package:

  1. npm install --save-dev motion-ui
  2. echo "declare module '*';" > resources/ts/global.d.ts
  3. To use in a component:
    import * as MotionUI from '../../../node_modules/motion-ui/dist/motion-ui';
  4. npm run dev

The code should transpile correctly. Also to ignore TypeScript errors one can use // @ts-ignore just above the line that errors but I would recommend resolving the error correctly.

@byteab
Copy link

byteab commented Jun 6, 2020

tried all the solutions not working! :(

@kud
Copy link

kud commented Jun 12, 2020

Same here.

image

I tried noImplicitAny, allowJs. Nothing.

@jQrgen
Copy link

jQrgen commented Dec 15, 2020

Same here

@jQrgen
Copy link

jQrgen commented Dec 15, 2020

How would one import this library in typescript? https://www.npmjs.com/package/grudus-timepicker

@uythoang
Copy link

i found this to be a helpful write up. https://medium.com/@chris_72272/migrating-to-typescript-write-a-declaration-file-for-a-third-party-npm-module-b1f75808ed2

in my case i just had to place the migration file in src/@types/@okta/library-name/index.d.ts and as long as the part after @types matched the import, it was picked up. inside can be just 1 line declaring the module

Thanks for this, I was racking my brain trying to figure it out. The only other thing I had to do was add the following to tsconfig.json:

{ "compilerOptions": { "paths": { "*": [ "node_modules/*", "src/@types/*" ] } } }

@blabadi
Copy link

blabadi commented Mar 30, 2021

In my case I had a module that declares a .d.ts and in that .d.ts they use an implicitly any module, which all the solutions above don't help with, but this did the trick:

{
    "compilerOptions": {
        "skipLibCheck": true,
        ...
    },
    ...
}

@microsoft microsoft locked as resolved and limited conversation to collaborators Mar 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests