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

Use d.ts specified types within a JavaScript Module Itself #14342

Closed
mjbvz opened this issue Feb 27, 2017 · 12 comments
Closed

Use d.ts specified types within a JavaScript Module Itself #14342

mjbvz opened this issue Feb 27, 2017 · 12 comments
Labels
VS Code Tracked There is a VS Code equivalent to this issue Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@mjbvz
Copy link
Contributor

mjbvz commented Feb 27, 2017

From microsoft/vscode#21454

TypeScript Version: 2.2.1

Code
For a javascript project
a.js:

export function abc( x, y ) { }

a.d.ts:

export declare function abc(x: number, y: number): boolean;

b.js

import { abc } from './a'

Expected behavior:
Within both a.js and b.js, the type of abc is (number, number) => boolean

Actual behavior:
Within a.js, the type of abc is (any, any) => void
Within b.js, the type of abc is (number, number) => boolean

The d.ts file is not applied within a module itself, only when it is imported into other files

@mjbvz mjbvz added the VS Code Tracked There is a VS Code equivalent to this issue label Feb 27, 2017
@mjbvz
Copy link
Contributor Author

mjbvz commented Feb 27, 2017

I also tried adding /// <reference path="./a.d.ts" /> to a.js but this did not give the correct types in a.js since there is no module import

@mhegazy
Copy link
Contributor

mhegazy commented Feb 27, 2017

A .d.ts is a replacement to .js, there is no easy way to map the structure of one to another. if you want to have the types in both, i suggest switching the .js to a .ts`

@mhegazy mhegazy added the Working as Intended The behavior described is the intended behavior; this is not a bug label Feb 27, 2017
@mhegazy mhegazy closed this as completed Feb 27, 2017
@rnemec
Copy link

rnemec commented Feb 27, 2017

@mhegazy - while technically, I would agree that it's WAD/WAI, from pragmatic perspective of smooth and incremental transition of JS-only projects to TS, it would be greatly beneficial to be able to define the types and definitions in separate non-production files and utilize the additional knowledge for VSCode/Intellisense, validation, etc.

And today - most of it works (as @mjbvz mentioned), except the module JS file itself (e.g. a.js above).

Again, not challenging "working as intended", but asking for considering extension of the "intended" for practical reasons of JS projects that cannot immediately just switch to TS.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 27, 2017

The mapping from a .d.ts to a .js file is not straight forward. There are may patterns in JS that can be used to achieve some of the ES6 declarations. e.g. a class. similarly a module shape in node is not the same as it is in ES6 (and .d.ts).

So given all of that, if you are the author of this .d.ts, consider using JSDoc to annotate your .js file.

@mjbvz
Copy link
Contributor Author

mjbvz commented Feb 27, 2017

@mhegazy Thank you for the explanation. This makes sense but I can also see @rnemec's point about migration. Is there any way to leverage something like /// <reference ... /> here to explicitly tell TypeScript to use a d.ts file for a module itself?

@rnemec
Copy link

rnemec commented Feb 28, 2017

Here is a thought (which may be more on vscode side rather than ts):
VSCode Intellisense is capable of using JSDoc type annotation for resolving the parameter types (and return, etc.) if there are any specified.
I wonder whether that logic can be extended to take .d.ts as an alternative to JSDoc (poor man approach: take the d.ts, internally produce JSDoc and apply it to the module).
But, also, I have no ***ing idea how are these designed/implemented. :-)

@rnemec
Copy link

rnemec commented Feb 28, 2017

I could understand the Mohamed's implicated complexity of all possible JS structures in a module (beyond what I asked for) may make it a big project by itself, thus rejected as "too much work and expecting too much bugs and bughancements coming afterwards".

Unless it's worth it considering the number of existing JS projects that cannot move yet (for whatever technical or political reasons).

Enough said - I'll shut up now.

@kaleb
Copy link

kaleb commented Oct 18, 2017

I have a team member that currently prefers not to switch to using typescript due to not wanting a build step. I do enjoy typescript and its associated tooling. I thought that a good compromise would be to use declaration files, but they do not work in their associated JS modules. I would like to use declaration files in their associated javascript file which would very helpful in refactorings and adding features and other maintenance tasks. Here is a (small) example project repo: https://gist.github.com/kaleb/e2f33c5f8ff3bc046a8b430ac8440c27

VSCode output from example repo

@mhegazy
Copy link
Contributor

mhegazy commented Oct 18, 2017

A file with a top-level import or export is a module. modules have their own scope, and they do not live in the global scope. This applies to .d.ts files as well. PersonStruct is a declaration within the module person.d.ts and not visible outside except thorough importing.

for this you have two options,

  1. put the declaration in the global scope, yo can do this today by updating your .d.ts
// person.d.ts
declare global { 
    type PersonStruct = PersonStruct;
}
  1. A new feature to add some way to indicate the source of the type for the compiler, that is currently tracked by [Salsa] Provide a JSDoc equivalent of import { ..} from "mod" #14377

@kaleb
Copy link

kaleb commented Oct 18, 2017

@mhegazy this is not an understanding about globals. This is a feature request to have a typescript declaration module declare types for a corresponding javascript module inside the module, not creating separate global types. I would prefer to write actual typescript, but I cannot currently. Another option would be to use JSDoc type annotations, but there are a few missing features in typescript JSDoc handling such as the @this tag. The request is to be able to declare a module's types in a separate file and be able to use them in that file as if I were writing in typescript. I just wanted to add my use cases here in case this request ever gets re-opened.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 18, 2017

This is a feature request to have a typescript declaration module declare types for a corresponding javascript module inside the module

I understand.. but module scopes have an existing meaning.. merging two module scopes is not something we have done before, and not sure how to reason about that. scopes is a well defied concept for most software developers, and having two files share the same scope is unexpected to say the least.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 18, 2017

I just wanted to add my use cases here in case this request ever gets re-opened.

I think the better way to do this is to allow you to define a new module, say person-types.d.ts and then import it some how in your JSDoc. which is tracked by #14377

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
VS Code Tracked There is a VS Code equivalent to this issue Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants