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

Type checking and IntelliSense with JSDoc typed js dependencies #29824

Open
5 tasks done
ahocevar opened this issue Feb 8, 2019 · 5 comments
Open
5 tasks done

Type checking and IntelliSense with JSDoc typed js dependencies #29824

ahocevar opened this issue Feb 8, 2019 · 5 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@ahocevar
Copy link

ahocevar commented Feb 8, 2019

Search Terms

JSDoc types dependenies

Suggestion

Possible alternative to #7546: Maybe type checking from JSDoc annotated dependencies can be achieved more easily in a different way. I have created a gist with a demo project that successfully uses a dependency (ol@6.0.0-beta.1 with fully JSDoc typed sources. This works well to get IntelliSense in VS Code for projects authored in pure JavaScript, but requires a not very obvious jsconfig.json configuration. Similar configurations (with tsconfig.json) partially work with TypeScript projects, but are very fragile quite easily, especially in more complex projects. And they only work when the "noEmit": true option is used.

However, it looks like a much lower hanging fruit than making .d.ts file generation work from JSDoc annotated JavaScript code (#7546). As the above example shows, it works already, but it should work out of the box and also in more complex configurations with TypeScript.

Use Cases

Full type checking and tsc support in both JavaScript and TypeScript projects with pure JavaScript dependencies. The dependencies are either JSDoc typed directly or published with their JSDoc typed sources.

This has to work without .d.ts files, because these cannot be generated from .js sources, neither with tsc nor reliably with third party applications.

Examples

Two possible scenarios:

  1. A package that only contains untranspiled JSDoc-typed modules. Unrealistic, because class inheritance is only fully recognized by TypeScript when the ES2015 class and extends keywords are used, which packages don't usually do, because it limits interoperability.
  2. A package that contains transpiled modules in addition to the original JSDoc-typed sources. Realistic and feasible, especially when source maps can point to these sources directly. An example for this would be ol@6.0.0-beta.1.

So let's assume the latter case is the more common one. If TypeScript would look for a tsconfig.json in dependencies (e.g. node_modules/ol/tsconfig.json), that file could have a config option to point to the annotated sources. Maybe something like

{
  "compilerOptions": {
    "jsSources": [
      "src/**/*.js"
    ]
  }
}

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@daKmoR
Copy link

daKmoR commented Mar 29, 2019

that sounds like a nice solution... currently this needs to be done "manually" e.g. if I want to get the JSDoc types of <your-package-name> then I need to set it up like so:

  "include": [
    "**/*.js",
    "node_modules/<your-package-name>/**/*.js"
  ],
  "exclude": [
    "node_modules/!(<your-package-name>)"
  ]

Some more details you can find a the blog bost Type-Safe Web Components with JSDoc

is there anything we can do to help?

@rbiggs
Copy link

rbiggs commented Sep 5, 2019

Yup, I hate having to put node modules with JSDoc comments in the includes definition. It just feels like a hack. I also consider it brittle. If you move something, this will break.

@rbiggs
Copy link

rbiggs commented Sep 9, 2019

I noticed a bug when using a module that consists of several files that import JSDoc types from other files. When such a project has an index.js file as the point of export, TypeScript fails to parse the JSDoc types imported from other files. There is a solution but it is a hack: importing one function from the file with the types used in other files. This forces TypeScript to recognize the imported types in the source files. #33136

@RangerMauve
Copy link

This is very painful and makes the claim that "typescript supports JSDoc" false in practice.

rowanmanning added a commit to Financial-Times/dotcom-reliability-kit that referenced this issue Oct 11, 2022
We can now generate TypeScript type declaration files for all packages
by running `npm run build`. This ensures that TypeScript projects which
import Reliability Kit modules will get proper type hinting and will not
throw errors during compliation.

This is a known issue, and it'd be nice if we didn't have to do it, but
it's either this or go wholesale TypeScript which involves a more
complex build step and it'd be a large-scale migration. I also still
think we shouldn't do it.

More context on the issue:

  * microsoft/TypeScript#19145
  * microsoft/TypeScript#29824
rowanmanning added a commit to Financial-Times/dotcom-reliability-kit that referenced this issue Oct 12, 2022
We can now generate TypeScript type declaration files for all packages
by running `npm run build`. This ensures that TypeScript projects which
import Reliability Kit modules will get proper type hinting and will not
throw errors during compliation.

This is a known issue, and it'd be nice if we didn't have to do it, but
it's either this or go wholesale TypeScript which involves a more
complex build step and it'd be a large-scale migration. I also still
think we shouldn't do it.

More context on the issue:

  * microsoft/TypeScript#19145
  * microsoft/TypeScript#29824
@trusktr
Copy link
Contributor

trusktr commented Sep 12, 2024

This has to work without .d.ts files, because these cannot be generated from .js sources, neither with tsc nor reliably with third party applications.

This actually can be done with tsc directly!

But it also requires a very non-obvious configuration. We can achieve it with the typesVersions field in package.json (not even in tsconfig.json!):

  "typesVersions": {
    "*": {
      "src/*": [
        "types/*"
      ]
    }
  },

This solves the problem that when you otherwise output the declaration files sibling to the JS files it breaks how the types are resolved in the JS files, so this trick allows placing the declaration files elsewhere instead of as siblings.

Here is a project with this configuration:

https://github.com/potahtml/pota/blob/6d5d04b2b19e993837b9fe78ac2e866cf1a1015a/package.json#L14-L20

See also the tsconfig.json there.

Now, when we run tsc, it will read the JS files (with JSDoc annotations) and output .d.ts files, allowing the project to be published!

Here's what the published types look like, including declaration source maps:

https://unpkg.com/browse/pota@0.14.133/types/

The package.json types field points to these types.


TLDR

It would be really great to have this working out of the box though, without

  • any of the potential bad side-effects that might come with the mentioned configuration (if any?),
  • and without the obscure configuration to begin with.

Ideally, because we're writing JS+JSDoc, we don't have to run a build at all, and TypeScript would just gather types directly from the JS files (I would not prioritize performance of reading types from JS over it simply working, but making tsc also output .d.ts files without an obscure configuration would allow optimizing it if desired)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants