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

noimplicitany and module without typings #13348

Closed
unional opened this issue Jan 8, 2017 · 19 comments
Closed

noimplicitany and module without typings #13348

unional opened this issue Jan 8, 2017 · 19 comments
Labels
Needs More Info The issue still hasn't been fully clarified

Comments

@unional
Copy link
Contributor

unional commented Jan 8, 2017

tsc 2.1.4

In 2.1 tsc support import module as any if they are installed through npm but no typings is found.

With --noImplicitAny, this is prohibited, meaning user need to get all typings for all modules again.

Should we consider this as an exception case for --noImplicitAny?

@mhegazy
Copy link
Contributor

mhegazy commented Jan 9, 2017

Should we consider this as an exception case for --noImplicitAny?

why?

@mhegazy mhegazy added the Needs More Info The issue still hasn't been fully clarified label Jan 9, 2017
@unional
Copy link
Contributor Author

unional commented Jan 9, 2017

Because users can benefit from --noImplicitAny and advanced control flow analysis while able to keep working if using libraries that do not have typings available.

By the way, would this consider explicit and remedy the situation?

import * as Something from 'some-module-without-typings'

declare module 'some-module-without-typings/*'

@mhegazy
Copy link
Contributor

mhegazy commented Jan 9, 2017

all you need is to declare the module. so something like

declare module 'some-module-without-typings/*' {
    var _a: any;
    export = _a;
}

@bradleyayers
Copy link

Is an even more general solution having this?

declare module '*' {
    var _a: any;
    export = _a;
}

@mhegazy
Copy link
Contributor

mhegazy commented Feb 24, 2017

Is an even more general solution having this?

All you need is declare module "*";

@mhegazy mhegazy closed this as completed Feb 24, 2017
@bradleyayers
Copy link

For this to be seamless we really need a solution for #12971

@slavafomin
Copy link

Hello there!

I have this module, called s3fs in my project, which doesn't provide any typings. I wanted to test it out, but I can't find a way to import it in my file without getting errors from compiler.

This line:

import S3FS = require('s3fs');

Gives me:

error TS7016: Could not find a declaration file for module 's3fs'. '…/node_modules/s3fs/index.js' implicitly has an 'any' type.

How do I make it explicitly any?

If I try to use declarations to handle this, then I'm getting this error:

error TS2665: Invalid module name in augmentation. Module 's3fs' resolves to an untyped module at '…/node_modules/s3fs/index.js', which cannot be augmented.

@mhegazy could you elaborate please? Thanks!

@dsamarin
Copy link

@mhegazy I get error TS2664: Invalid module name in augmentation, module '*' cannot be found.

Or when I try to be specific in my case I get: error TS2665: Invalid module name in augmentation. Module '@material/checkbox' resolves to an untyped module at 'T:\node_modules\@material\checkbox\index.js ', which cannot be augmented.

I would love to have an import as an explicit any.

@Spongman
Copy link

Spongman commented Apr 11, 2018

Should we consider this as an exception case for --noImplicitAny?

why?

because otherwise this simple use case is a pain in the neck?

@mhegazy
Copy link
Contributor

mhegazy commented Apr 11, 2018

@mhegazy I get error TS2664: Invalid module name in augmentation, module '*' cannot be found.

This means you are putting the declare module in a module file.. just put the declaration in a .d.ts file that is not a module (i.e. does not have export or import on the top level).

@willmtemple
Copy link

@mhegazy Is there still no way to make the any type of an untyped import explicit? I want to use noImplicitAny in my codebase, which has a relative import of a plain JavaScript module that is in the source tree. Normally, I would just install the module using NPM and then declare it, but since we have had to modify the module and may have to modify it extensively, and since the module is inactive upstream, I've just merged it into our tree (abridged, below):

.
├── lib
│   ├── core.ts
│   ├── js-type-layer.ts <-- The TS module that imports and provides the JS module
│   ├── api.ts
├── vendor <-- The plain JS module directory
│   └── js-module
├── node_modules
│   └── @types
├── package.json
├── package-lock.json
└── tsconfig.json

Currently I do the following in a TypeScript module with "noImplicitAny" : false:

import _m = require("../vendor/grove-js");

declare namespace grove {
    //...
}

export default _m;

If I enable noImplicitAny, then the first line errors, as _m is implicitly typed as any. But, you cannot declare a relative module in TypeScript, so it's not possible (afaict) for me to convert this into a declarations file and declare the grove module that way.

This seems like a bug to me, since the error is not that the type of the import is any, only that that type is implicit, and there doesn't seem to be any way for me to make that type explicit. Hacking away TypeScript's module resolution checker by doing declare module "*" doesn't seem like a good solution, and even when I do use declare module "*", I get errors about namespace '"*"' has no exported member ...

It's simple enough for me to leave noImplicitAny off in my project, but it's a shame to overlook this feature because I want to import a JS library using a relative import.

@mhegazy
Copy link
Contributor

mhegazy commented Jul 13, 2018

why not create a grove-js.d.ts file and put it next to the .js file?

@willmtemple
Copy link

This results in grove-js.d.ts is not a module. Then I change the import line to import grove from './grove-js/' and change the .d.ts file to specify declare module "*grove-js/" and this seems to satisfy tsc, but then I turn on noImplicitAny again, and the result is the same: the import is any-typed.

@mhegazy
Copy link
Contributor

mhegazy commented Jul 16, 2018

Can you share a repro?

@Spongman
Copy link

Spongman commented Jul 16, 2018

also, it seems onerous to require the creation (and continual maintenance) of a .d.ts for every imported .js library just to enable the project-wide noImplicitAny flag.

surely if you're importing a .js file doesn't that import itself explicitly declare that everything imported is of type any (unless the compiler can infer otherwise) ?

@mhegazy
Copy link
Contributor

mhegazy commented Jul 16, 2018

also, it seems onerous to require the creation (and continual maintenance) of a .d.ts for every imported .js library just to enable the project-wide noImplicitAny flag.

First, --noImplicitAny tells the compiler to raise a warning whenever it sticks an any type on a name that the user has not specified. a module import from an unknown and un-typed module fits that description.

Second, you do not need a file unless you want to go into details of the module declare module "foo"; is all you need. see http://www.typescriptlang.org/docs/handbook/modules.html#shorthand-ambient-modules

@wolframkriesing
Copy link

wolframkriesing commented Aug 4, 2018

I prepared a tiny repo, which

  • has an index.js file
  • an index.d.ts

when setting "noImplicitAny": true tsc fails :(
i believe that is what @Spongman and @willmtemple mention.
would love to see help on that
wolframkriesing/implicit-any-and-js-files@5bdb2bc

UPDATE: updated link, had to ensure that the d.ts is really used by tsc

@wolframkriesing
Copy link

@mhegazy i think the repo above reproduces the behavior described above

@willmtemple
Copy link

@mhegazy you can check out https://github.com/LaboratoryForPlayfulComputation/pxexec-runtime as well. We're trying to type the grove-pi javascript library. As is, I have lpc-grove-translation.ts and a module in lpc-grove-js/index.js. Currently, this repository is in a stop-gap state where it works but doesn't actually typecheck (seems like the namespace grove declaration doesn't bind to the export at the end, which I expected. In fact, I cannot use the noUnusedLocals compiler check because it sees declare module grove as unused.

When I want to typecheck the code, I rename lpc-grove-translation.ts to lpc-grove-js.d.ts and comment out the module declarations in the file. This gets me typechecking but the resulting error is that lpc-grove-js is not a module.

Again, if I were importing this library using npm, this would be very simple to do, as I would just declare the module in a declarations file, but I cannot, as far as I can tell, declare a relative path import,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs More Info The issue still hasn't been fully clarified
Projects
None yet
Development

No branches or pull requests

8 participants