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

Typescript cannot locate the type information of the core module. #2682

Closed
hallaji opened this issue Sep 11, 2020 · 37 comments
Closed

Typescript cannot locate the type information of the core module. #2682

hallaji opened this issue Sep 11, 2020 · 37 comments
Labels
autoclose Flag things to future autoclose. bug help welcome Could use help from community

Comments

@hallaji
Copy link

hallaji commented Sep 11, 2020

Hi there 👋

I'd like to import the core and only necessary language files. I tried as below but then realised that there is something wrong in package regarding typings.

import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
Could not find a declaration file for module 'highlight.js/lib/core'. 

I have not imported the index module i.e. import hljs from 'highlight.js. So, typescript can't locate the type information for the core module from a subfolder. I believe the solution might be creating .d.ts file for every subfolder and file in your case.

I quickly fixed this issue locally by creating a core.d.ts file under lib directory. So, I guess we need to declare the entire API that the library exposes.

@hallaji hallaji added the enhancement An enhancement or new feature label Sep 11, 2020
@joshgoebel
Copy link
Member

I quickly fixed this issue locally by creating a core.d.ts file under lib directory.

Is there any easy way we can tell it that that is essentially the same as importing the whole library at least from a types perspective?

I believe the solution might be creating .d.ts file for every subfolder and file in your case.

This isn't going to happen.

@hallaji
Copy link
Author

hallaji commented Sep 11, 2020

Well, really quick solution would be to move/declare your types to ./lib/core.d.ts and then just reference the core in ./lib/index.d.ts or do the opposite.

highlight.js
├── lib
│   ├── languages
│         └── ...
│   ├── core.d.td
│   ├── core.js
│   ├── index.d.ts
│   └── index.js

core.d.td

declarations here

index.d.ts

/// <reference path="./core.d.ts" />

Of course with this fix "types": "./lib/index.d.ts" in package.json.

@joshgoebel
Copy link
Member

│   ├── languages
│         └── ...

Why include this at all? No changes need to be made here, correct or no? Did you include it just for "context"?

@hallaji
Copy link
Author

hallaji commented Sep 12, 2020

You've already declared languages/* modules in core.
Correct, I assume we have to import at least one of the core or index modules in order to benefit from highlight.js. So Typescript will find languages/* there.

@joshgoebel
Copy link
Member

Of course with this fix "types": "./lib/index.d.ts" in package.json.

And I assume my VS Code "intelligence" for all things type related (even though our project is annotated JS) will continue to just work since I think it's all predicated upon this magic line in package.json, right?

If so I think a PR for this would be more than welcome.

@hallaji
Copy link
Author

hallaji commented Sep 12, 2020

Sure, I will.
When someone imports the library, types in package.json tells the TS compiler where to look for your library’s types. I believe there is nothing to worry about vs intelligence.

@thealjey
Copy link

thealjey commented Nov 8, 2020

you cannot import anything that is in a sub-folder because typescript is not able to locate the type definitions
the only good solution is for the "types/index.d.ts" file to be moved into the root of the project

for now, the only solution that worked for me is a reference comment like this:

/// <reference path="../../node_modules/highlight.js/types/index.d.ts" />

@joshgoebel
Copy link
Member

joshgoebel commented Nov 8, 2020

I'm just waiting for a simple PR to solve this. @hallaji Made it sound pretty trivial... If someone could provide a small repository test project with steps to reproduce the issue it'd be much easier to test the fix when someone makes a PR. @thealjey IE, if you're saying the proposed fix won't work then having a simple test case would go a long ways toward helping us find a proper fix.

I'm quite confused why simply moving the file would help. It seems the WHOLE purpose of the types package.json key is to educate any "consumers" about where they can find this file. Is there just "magic" that works with a root file? If so why can't that same magic consider root/package.json/types?

My understanding of this issue:

  • import hljs from 'highlight.js' works (the system kicks in, looks at types, and finds and uses the type file).
  • import hljs from 'highlight.js/lib/core' does NOT work, but should. (the system gets confused because of /lib/core)

@joshgoebel joshgoebel added bug help welcome Could use help from community and removed enhancement An enhancement or new feature labels Jan 7, 2021
@joshgoebel
Copy link
Member

you cannot import anything that is in a sub-folder because typescript is not able to locate the type definitions

Why? Isn't this the whole purpose of types in package.json?

the only good solution is for the "types/index.d.ts" file to be moved into the root of the project

I don't find any improvement after moving the file.

@joshgoebel
Copy link
Member

I don't understand why this seems to work for faker, but not us:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a92542482f08238ece6650ccbd68815d5b33a9cd/types/faker/index.d.ts

As far as I can tell we're following the exact same pattern with declare module.

@joshgoebel
Copy link
Member

joshgoebel commented Mar 24, 2021

Could not find a declaration file for module 'highlight.js/lib/core'.

@hallaji

Did you try npm install @types/highlight.js? That fixes the issue for me.

I'm not sure why tsk needs a stub package to work properly though.

@joshgoebel joshgoebel added the autoclose Flag things to future autoclose. label Mar 25, 2021
@firelizzard18
Copy link

Did you try npm install @types/highlight.js? That fixes the issue for me.

This does not fix the issue for me. node_packages/@types/highlight.js only contains LICENSE, README.md, and packages.json, so adding it shouldn't do anything. The package file doesn't have anything useful in it.

@joshgoebel
Copy link
Member

joshgoebel commented Mar 31, 2021

@types/highlight.js includes a type file that imports then re-exports our own types. Or it did just the other day...

Maybe that's not needed anymore? I really don't understand all the "magic" that is happening here as far as when and where TS looks for type files.

@firelizzard18
Copy link

I believe you, but the version NPM pulled for me today doesn't:

# npm install @types/highlight.js

up to date, audited 165 packages in 840ms

17 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
# ls node_modules/@types/highlight.js 
LICENSE       README.md     package.json

It may not be what you're looking for as a test case, but I have a pretty simple real-world use case here: https://gitlab.com/ethan.reesor/vscode-notebooks/simple-renderers/-/blob/master/src/highlight/main.ts

The /// <reference path="..." /> workaround works for me, so I'm not too concerned.

@joshgoebel
Copy link
Member

joshgoebel commented Mar 31, 2021

DO you need to be inside a TS project or something? Not sure but I saw this yesterday but today in my test project it works fine:

~/w/tmp_app(main|✚3…1) % rm -rf node_modules/@types/highlightjs/          
~/w/tmp_app(main|✚3…1) % npm install @types/highlightjs                    

added 1 package, and audited 12 packages in 707ms

found 0 vulnerabilities
~/w/tmp_app(main|✚3…1) % ls node_modules/@types/highlightjs/        
LICENSE       README.md     index.d.ts    package.json

@joshgoebel
Copy link
Member

% npm -v                                           
7.6.3
~/w/tmp_app(main|✚3…1) % tsc -v                                            
Version 4.2.3

@firelizzard18
Copy link

% npm -v 
7.6.3
% tsc -v
Version 4.0.5

@firelizzard18
Copy link

OK wow...

- @types/highlight.js
+ @types/highlightjs

As far as I'm concerned, that solves my problem.

@joshgoebel
Copy link
Member

joshgoebel commented Mar 31, 2021

Oh yikes and that's not even the correct name either - I didn't realize @types had two. ugh. Lets see if I can fix this now. :)

@joshgoebel
Copy link
Member

joshgoebel commented Mar 31, 2021

@hallaji Please try:

npm install @types/highlight.js
npm install @types/highlightjs

Right now you need highlightjs but that's incorrect so I'm working to see if we can get the naming fixed. If I don't hear back from you I will assume this is resolved.

@joshgoebel
Copy link
Member

joshgoebel commented Mar 31, 2021

that solves my problem.

And now I'm even more confused how TS finds the types though... does it just load EVERYTHING with @types magically regardless of naming? Previously I thought perhaps it was done by name matching, except our names don't match - so that can't be it.

@firelizzard18
Copy link

does it just load EVERYTHING with @types magically regardless of naming?

It must, unless it does something like compare after removing all non-alphanumeric characters. I wonder if Typescript's normal type resolution (types: in package.json) only works in the simple case of the base import, e.g. from 'highlight.js' and not from 'highlight.js/some/path'.

Either way, this issue is pretty frustrating (from your perspective) - the @types package just imports and reexports HLJS...

import highlightjs = require('highlight.js');

export = highlightjs;

If that works, why don't the definitions in your package. Maybe this is a tsc issue.

@joshgoebel
Copy link
Member

I wonder if Typescript's normal type resolution (types: in package.json) only works in the simple case of the base import, e.g. from 'highlight.js' and not from 'highlight.js/some/path'.

Indeed. But seems pretty silly since it's easy to see that the longer strings points into a package and therefore it could use the package type modules to potentially help resolve the reference. Not sure why that would be a bad thing to try.

@joshgoebel
Copy link
Member

joshgoebel commented Apr 1, 2021

@firelizzard18 @hallaji

I'm still running this down (to see what we might want to change but seems you can also fix this simply by first importing the top-level package) though I'm not sure what packaging implications that might have (if any):

import 'highlight.js' // this line makes the following line know where the types are
import hljs from 'highlight.js/lib/core'

This is really all the @types/highlightjs stub is accomplishing anyways. Right now it seems there should be no @types package at all, so in the end there will likely be no @types package to install. We'll either change our codebase slightly (splitting types into multiple files) or change our guidance to recommend the above or adding us to typeRoots.

@joshgoebel
Copy link
Member

joshgoebel commented Apr 1, 2021

@andrewbranch If we just go ahead and add core.t.ds and common.t.ds, etc... should those import and re-export types from types/index.t.ds, should types/index.t.ds reference core or some other pattern? or is the top-level typing no longer necessary at that point? I'm a bit confused on best practices on where the canonical types go.

We have a lot of imports that are effectively the same:

import "highlight.js"             // engine, all grammars
import "highlight.js/lib/core"    // engine, no grammars
import "highlight.js/lib/common"  // engine, our "common" group of grammars

All of these export the same types... just the amount of grammars they add vary greatly. I suppose technically our build system could just duplicate the type file multiple times, but I'm sure that's technically not the correct way to do these things so I'd love to know the right way.

@andrewbranch
Copy link

Yeah, I think importing from index.d.ts would make sense in this case.

@joshgoebel
Copy link
Member

And index.d.ts can still live in the types folder with a reference in package.json types then?

@joshgoebel
Copy link
Member

joshgoebel commented Apr 2, 2021

@andrewbranch Would you mind having a look at #3073

Nothing seems to work, or it only half works... I have:

import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'

hljs.highlight("test","test")

IN a test project but I keep getting:

% tsc b.ts --strict --esModuleInterop
b.ts:7:24 - error TS7016: Could not find a declaration file for module 'highlight.js/lib/languages/javascript'. '/Users/jgoebel/work/tmp_app/node_modules/highlight.js/lib/languages/javascript.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/highlight.js` if it exists or add a new declaration (.d.ts) file containing `declare module 'highlight.js/lib/languages/javascript';`

7 import javascript from 'highlight.js/lib/languages/javascript'
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 1 error.

I don't understand WHERE it wants the ambient export or what triggers the ambient exports to "count", ie if core just imports index, does that magically bring all the ambient exports into scope...

Right now I have the ambient export pattern in BOTH index and core, and still it doesn't work.

@joshgoebel
Copy link
Member

joshgoebel commented Apr 2, 2021

OK the only way I've gotten it to work so far is:

  • index is NOTHING but ambient modules (no top-level declarations other than declare module, which means it declares highlight.js as well - that's the part that seems strange to me for some reason.
  • core is just import x from "highlight.js"; export x

I'll push what I have... is this the right track?

@joshgoebel
Copy link
Member

@firelizzard18 @hallaji Any chance either of you could test the changes in the linked PR?

@firelizzard18
Copy link

@joshgoebel It works for import hljs from 'highlight.js/lib/core', though I had to add build/ to the path in order to use the MR branch directly. import xml from 'highlight.js/lib/languages/xml' still does not work unless I create build/lib/languages/xml.d.ts as a copy of core.d.ts.

@joshgoebel
Copy link
Member

joshgoebel commented Apr 3, 2021

import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'

hljs.highlight("test","test")

In my sample project that works. core imports highlight.js so the ambient modules should be registered so that the language import works. Your might not be working because you're adding build to the path - which changes everything. You need to actually COPY the build into node_modules as it would be in real life to properly test it.

The import path must literally be:

highlight.js/lib/languages/* with no other prefixes

@firelizzard18
Copy link

@joshgoebel When I ran cp -r /tmp/highlight.js/build ./node_modules/highlight.js, it worked

@joshgoebel
Copy link
Member

Sounds about right. TS is picky. :)

@joshgoebel
Copy link
Member

Closing via #3073.

@joshgoebel
Copy link
Member

sigh And upon moving all the types into declare module 'highlight.js' { now my type checking in VS Code is entirely broken... it no longer "automagically" finds any of the types as it did when they were declared at the top-level of index.d.ts... and that's the only reason I added the types in the first place...

Is there some way to fix this?

@blujedis
Copy link

FYI setting reference seems to play nice as near as I can tell.

In my case the file importing core is in src/filename.ts

/// <reference path="../node_modules/highlight.js/types/index.d.ts" />
import hljs from 'highlight.js/lib/core';

From there register your languages:

import typescript from 'highlight.js/lib/languages/typescript';
hljs.registerLanguage('typescript', typescript);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autoclose Flag things to future autoclose. bug help welcome Could use help from community
Projects
None yet
Development

No branches or pull requests

6 participants