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

[Salsa] Provide a JSDoc equivalent of import { ..} from "mod" #14377

Closed
mhegazy opened this issue Mar 1, 2017 · 52 comments
Closed

[Salsa] Provide a JSDoc equivalent of import { ..} from "mod" #14377

mhegazy opened this issue Mar 1, 2017 · 52 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript VS Code Tracked There is a VS Code equivalent to this issue

Comments

@mhegazy
Copy link
Contributor

mhegazy commented Mar 1, 2017

Given an implementation of a class:

// file.js

export default class File {
   ...
}

How can you use the type without importing the module:

// another
export default Util {
   /** @param {File} file  */
   getFile(file) {
   }
}

One option is to use @module
e.g.:

   /** @param {module:./file:File} file  */
   getFile(file) {
   }
@bobzhang
Copy link

bobzhang commented May 10, 2017

I hit the same issue today, the idea is to not relying on transpiling on server side, for example, I want to define my own object type like this, below does not work:

/**
 * @typedef {Object} Watcher
 * @property {string} dir
 * @property {fs.FSWatcher} watcher
 */

The editor complains that it does not understand fs

@mhegazy
Copy link
Contributor Author

mhegazy commented May 10, 2017

We will proceed with #14056 for now, try to special case classes.

@mjbvz mjbvz added the VS Code Tracked There is a VS Code equivalent to this issue label Jun 29, 2017
@ste2425
Copy link

ste2425 commented Jun 29, 2017

Such a workflow would also be brilliant for Angular1 apps where you may have a main file that injects all your dependencies and a separate file that specifies your controller. The controller file exports a function/class. It receives its dependencies but does not inject them directly, being able to tag them using JSdoc as a type that was defined in a different file in your workspace would be invaluable there.

@drKnoxy
Copy link

drKnoxy commented Jul 13, 2017

@mhegazy did you ever get anything working along these lines? Trying to reference a js class from a typedef, sounds like the same problem.

@goodmind
Copy link

Any progress here?

@sergeysova
Copy link

sergeysova commented Sep 28, 2017

Maybe?

/**
 * @import {File} from './file'
 */

/**
 * @param {File} file
 */
getFile(file) {
}

@e00dan
Copy link

e00dan commented Nov 10, 2017

Helo, was there any update on this? It would be great to have this.

@sofib
Copy link

sofib commented Dec 1, 2017

Having a straightforward way to do this is a must in any decent code design where one needs to inject a dependency. Any updates, please?

@hitendramalviya
Copy link

Any update on this?

@clshortfuse
Copy link

I suggest we use the same syntax as Closure does:

/** @param {./foo.Foo} Foo */
function(Foo) {}

https://github.com/google/closure-compiler/wiki/JS-Modules#type-references

You can also write the syntax as /** @type {./path/to/module.propName} */

@igrek8
Copy link

igrek8 commented Jan 13, 2018

Sadly, the conversation has not gone far to implement this feature:( Very much looking forward to having this added.

@joma74
Copy link

joma74 commented May 31, 2018

Is/Can the following case be covered/coverable?

type of webpack.Configuration defines devServer as any. So would like to apply type of webpack-dev-server.Configuration to the devServer property.

In the following code devServer is still identified as (property) webpack.Configuration.devServer?: any.

/**
 * @type {import ("webpack").Configuration}
 */
var webpackConfig =
  {
    /**
     * @type {import("webpack-dev-server").Configuration}
     */
    devServer: {
      port: 8080,
      watchContentBase: false,
      hot: true,
      stats: "errors-only",
      host: "0.0.0.0",
    },

@thw0rted
Copy link

You could put in a PR against DefinitelyTyped to fix @types/webpack, then you wouldn't have to worry about it. In fact, the typings file I'm looking at even has "// TODO: Type this" on devServer :D

@joma74
Copy link

joma74 commented May 31, 2018

Thanks for the hint;
Still I think that my more nearer/specific typing may/should be applied. On the general case that artifacts are meant to be not coupled.

When extracted, the following case displays (property) devServer: WebpackDevServer.Configuration for webpackConfig.devServer.

/**
 * @type {import("webpack-dev-server").Configuration}
 */
const devServer = {
  port: 8080,
  watchContentBase: false,
  hot: true,
  stats: "errors-only",
  host: "0.0.0.0",
}

/**
 * @type {import ("webpack").Configuration}
 */
var webpackConfig = {
    devServer
}

@vbogach
Copy link

vbogach commented Jun 5, 2018

Unfortunately, this code breaks my jsdoc generation:

/**
 * @typedef {import("./foo").Bar} Bar
 */

Results into:

ERROR: Unable to parse a tag's type expression for source file in line 1 with tag title "typedef" and text "{import("./foo").Bar} Bar": Invalid type expression "import("./foo").Bar": Expected "!", "=", "?", "[]", "|" or end of input but "(" found.

when I execute jsdoc. Could you give any hints on how to keep my jsdoc working?

@mhegazy
Copy link
Contributor Author

mhegazy commented Jun 6, 2018

looks like a request for your jsdoc generation tool.

@Thaina
Copy link

Thaina commented Jun 21, 2018

@mhegazy Does not seem like that work

image

Currently now only this below work

image

@mhegazy
Copy link
Contributor Author

mhegazy commented Jun 21, 2018

you have declared a type alias called firebase whose type is typeof import('firebase'), but that has nothing to do with the variable firebase that is not defined.

consider adding a .d.ts file in your project with a declaration for firebase:

// globals.d.ts

declare var firebase: typeof import("firebase");

also /* global ... */ is not supported at the moment, #15626 tracks adding that.

@Thaina
Copy link

Thaina commented Jun 25, 2018

@mhegazy It is still the same that it need to have d.ts separate from js while I would like to declare in js purely (or don't even need to declare anything if possible)

ps. The /* global */ there is not related. I just put it to satisfied eslint

@Thaina
Copy link

Thaina commented Jun 25, 2018

@mhegazy Also if I put the declare var in some d.ts into the project. I need to actively open it in the tab. Else it was not counted in the engine

It work fine here

image

Until I close the file

image

edit: Seem like this was cause from putting that d.ts in subfolder of the project. Bring out to root folder would not happen

@mhegazy
Copy link
Contributor Author

mhegazy commented Jun 25, 2018

Also if I put the declare var in some d.ts into the project. I need to actively open it in the tab. Else it was not counted in the engine

Make sure you add a jsconfig.json at the root of your project.

@niedzielski
Copy link

Unfortunately, this code breaks my jsdoc generation:

/**
 * @typedef {import("./foo").Bar} Bar
 */

This issue is encompassed in jsdoc/jsdoc#1537.

JSDoc is not a very active project so I think it's unlikely to add support for this functionality. Unfortunately, this makes it very difficult to migrate vanilla JavaScript to TypeScript type checking while still appeasing JSDoc stakeholders wary of change since the new syntax breaks JSDoc execution. I've experimented with /// <reference path="foo.js" /> syntax but haven't been able to find a substitute that will allow TypeScript to pull in the JSDoc typing.

If it were supported, the /// import {Foo} from './bar' syntax proposed by @joma74 or even /** @import {Foo} from './bar' */ by @sergeysova would work for most folks since the default JSDoc config allows unknown tags such as @import.

@SystemDisc
Copy link

SystemDisc commented Jul 3, 2018

@joma74 You could actually do the following:

/**
 * @type {import('webpack').Configuration & { devServer: import('webpack-dev-server').Configuration }}
 */
var webpackConfig = {
  devServer: {
    port: 8080,
    watchContentBase: false,
    hot: true,
    stats: 'errors-only',
    host: '0.0.0.0',
  },
  // ...
};

@Thaina
Copy link

Thaina commented Jul 16, 2018

@mhegazy

declare var firebase: typeof import("firebase");

I made this file in project and it was add to .d.ts and normal intellisense work correctly

image

However the JSDoc does not register the class in namespace loaded this way

image

@mhegazy
Copy link
Contributor Author

mhegazy commented Jul 16, 2018

Can you share a project i can look at?

@Thaina
Copy link

Thaina commented Jul 17, 2018

@mhegazy Thank you

I was make it compact so might need to run npm install first

TTTT.zip

@nemoDreamer
Copy link

I'm surprised that this was closed as "fixed", when the intent was to "provide a JSDoc equivalent of ...".

/** @typedef {import('foo').Bar} Bar */ is not a "JSDoc equivalent", since it's invalid JSDoc...!

As already pointed out by #14377 (comment), it would be great to have a real equivalent that could would simultaneously let Typescript-in-Javascript know about the Bar type and not have JSDoc complain about not knowing Bar in regular @type {Bar}/@param {Bar} bar usage throughout the file.

❤️

@vschoener
Copy link

Sadly, we still have nothing good to use? :(

@SystemDisc
Copy link

It would be great if this issue could be reopened to continue discussion and not let it get lost.

@saschanaz
Copy link
Contributor

Do even JSDoc have an official syntax for type import?

@maxjf1
Copy link

maxjf1 commented May 16, 2019

Is there an way to reference an class as an argument without importing it?

EDIT: For now only this worked for me

/** @typedef {import('../my-class').default} MyClass */

@ricardohbin
Copy link

I did a little patch in JSDoc to does not breaks and accepts {import('./file').Foo} -> ricardohbin/jsdoc#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript VS Code Tracked There is a VS Code equivalent to this issue
Projects
None yet
Development

No branches or pull requests