-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Proposal: new ES6 style syntax to apply typeof on an ambient external module #2357
Comments
We've heard requests for something like this many times now and it has a lot of merit. I would aim to keep it a relatively simple feature, basically an type FileSystemType = typeof import "FileSystem"; We already allow dot to select members in a type FileSystemDefaultExportType = typeof (import "FileSystem").default;
type FileReaderType = typeof (import "FileSystem").FileReader; |
I think that looks quite reasonable (not sure if However, have you considered using the type FileSystemType = typeof module "FileSystem"; // <-- looks good to me even without the parens
type FileSystemDefaultExportType = typeof (module "FileSystem").default;
type FileReaderType = typeof (module "FileSystem").FileReader; The problem with
(your proposal), or
(my first version), instead of the more grammatically correct
e.g. the syntax: typeof (FileReader from "FileSystem") (my second version), though under the mind-boggling ES6 semantics, Nevertheless having the module name first may be a big advantage for editor auto-completion and would allow quicker type-checker feedback on the module name, so I would understand why an alternative might be preferred (and now that I considered your approach, I actually like it better, but only when used with the Anyway, whatever syntax is chosen, I'm glad this feature is being considered as being able to easily extract types from external module declarations would be a highly useful feature for myself, and possibly others. I develop libraries that are mostly targeted to work both on the web and in Node, so I almost always load modules conditionally and at an as-needed basis (a pattern that is very frequent in CommonJS development - even the Node manual uses it extensively). And although having spent much time using languages like C# and C++, it seems that being imposed an (artificial, in many cases) requirement to "statically" declare module imports ahead of time has began to appear a bit outdated and rigid to me, and frankly not very characteristic of the more dynamic style of JavaScript. Seeing the freedom and flexibility the dynamic approach gives, I would actually go as far as saying it would be interesting to consider [TypeScript] allowing modules to be ["officially"] imported everywhere, including, for example, in conditionals and loops (CommonJS/Node has a caching system, so the module will only be loaded once), however, ES seems to have gone in a different direction, but again I don't really have the knowledge and foresight to analyze that right now as I currently don't know a lot about it (and of course, haven't really used it practice). |
I tried to write a proposal to continue the (diverging) discussion in a different issue (mostly to express my ideas in a more coherent and organized way and to offer some of my own suggestions). See: |
Need more compelling use cases than "not wanting an intermediary import" to justify complicating the syntax here. |
As a continuation to #2346 I decided to re-target the discussion specifically with the new ES6 module syntax (#2242) in mind, and open it as a new issue (my apologies if I got some of the ES6 module semantics wrong here, as it's still very new to me).
I propose the following syntax to get the type of an ES6 (or the older variant of an) ambient external module, or some specific export of it. There are two versions, where the second one (my personal preference) is more succinct and readable as it omits the
import
keyword. Here are some examples (In many cases I'm still not sure of which version is "best" so I provided multiple alternatives):The syntax (1st version)
Get entire namespace type:
Get specific export type:
Get default export type:
Some import expressions don't really make sense when a (single) type is needed:
It would also be very useful to use it directly as a type within a regular variable declaration, like this:
I think this looks quite reasonable, and should be relatively easy to parse. Though it could be made even simpler..
The syntax (2nd version)
The
import
keyword could even be omitted entirely to yield a more succinct and natural syntax (that's still not very difficult to parse). Examples:Example use cases
Since
typeof
only gets the type information (or symbols) for the module exports, it should be usable in any scope, including within internal modules, functions, conditional statements or even loops. This would allow to attach type information to a dynamically or conditionally loaded module, such as in:or even used with a frequent CommonJS import pattern where only a specific member is dynamically loaded from a module:
or used to load a replacement or polyfill for some module or export that has a different name, but conforms to the same type specification, essentially using the type as an interface:
Your comments
I'd be interested in your opinions on this? and in case the language designers have different ideas for a syntax to get this sort of type information, I'd like to hear all about it!
The text was updated successfully, but these errors were encountered: