-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Feature request: better support for typing async imports #11611
Comments
function doSomethingAsync(): void {
let x = require(['jquery'], function ($) {
$('#foo');
});
}
declare function require(modules: ['jquery'], f: ($: JQueryStatic) => void); Is not that much extra code to maintain. Module import syntax and semantics need to converge instead of having more variants supported by more tools. There are proposals to add new forms of imperative imports to ECMAScript. If that happens I imagine TypeScript would transpile these into corresponding syntax for the target module format. |
@aluanhaddad but where does the And maybe jquery wasn't the best example. Replace it with some pure typescript module, written with ES6 imports. Importing it with
If by this you mean we should have a single way to do async imports, then sure, I can jump on board with that; but the fact remains there is no "es6+ async import" spec. But as someone who writes code that targets the browser, we need a solution that can do both sync and async imports; wishing away async imports may work server side, but it's not a rational choice in the browser. |
If the TypeScript file has exports we can use them just like we would from a declaration file. Even if it were a declaration file, TypeScript would retain imports for the corresponding module if we use any values from it in value position. I agree there is an issue here but it is not really a TypeScript issue as much as an issue with ES Modules. ES Modules couple declaration and definition very heavily. I don't have a good solution. |
By the way there are some proposals you may find of interest. |
I'm not totally clear what you mean by this. Probably it'll be more clear with an example: let's suppose I have a file foo.ts:
And then within
Now I can manually type Anyhow, to be totally clear: I'm hoping for a solution soonish - probably before ES6 settles on any standardized way of doing things. Fwiw, I looked over those two proposals - nested imports doesn't seem to address how to do them asynchronously, but With only minor additions of syntax to typescript, I guess what I would like to see would be something like this:
Where we'd add this Now I'll admit that I don't love what I'm suggesting because it means we end up duplicating our module names, and need to also check that the types of the arguments to the callback match the order of the module names in To do an even better job on AMD |
I would add that implementing this would not be as simple as that, since it probably needs to work as a type operator, e.g. load(moduleName:string): shapeof moduleName; moreover, anything we do here will need to respect the module resolution logic we have today, and other commandline options it is worth noting that given how the compiler is architected, this is not a trivial change. |
sure, that's totally understandable - I'd definitely want it to use the In my opinion it's a worthwhile change, since it fills a real need we have
On Mon, Oct 17, 2016 at 2:41 PM Mohamed Hegazy notifications@github.com
|
Worth noting that there is a related proposal in TC39 for asynchronus imports, see https://github.com/domenic/proposal-dynamic-import. |
wouldn't implementing the TC also require a lot of this work to happen? what I'm hearing is that this isn't trivial because the module resolution code isn't properly abstracted / easy to use in another place; and any ES7+ async imports deal will have the same challenge during implementation, right? |
yes. I am just adding a related topic. |
@dgoldstein0 I am quite curious how often you run into this problem. I have spent a lot of time working on TypeScript + AMD and TypeScript + SystemJS projects. The only times when I found myself needing to write require(['dep1', 'dep2', 'depN'], (dep1, dep2, depN) => {
...
}); or Promise.all(['dep1', 'dep2','dep3'].map(dep => SystemJS.import(dep)))
.then(([dep1, dep2, dep3]) => {
...
}); were to load very specific, very large bundles. This was fairly rare (~3-4 times in a medium sized app) so the burden of manually typing them was not significant. |
That's a good question. The general answer though is not enough - we have On Sun, Oct 23, 2016, 11:27 AM Aluan Haddad notifications@github.com
|
More than two dozen explicit dynamic imports would a be a lot of XHRs from a production point of view. I don't think your approach will improve performance during development if you are loading single files since the the api calls in the emitted JavaScript are already async on a per module dependency basis and get cached by RequireJS. This is really something that helps with bundles, otherwise, I believe you will just make your life harder. I say this especially because |
We are doing bundling too, and use a bunch of tricks parallelize module For some context: The idea of our async loading is going to be for code Anyhow as we do more async loading we'll definitely figure out more On Wed, Oct 26, 2016, 2:55 AM Aluan Haddad notifications@github.com wrote:
|
I believe the |
Currently, typescript has great support for ES6 style imports - e.g.
typescript is able to know that
"jquery"
here is whatever defines the jquery module, and$
gets the type associated with jquery's exports.However, if you try to async load code in typescript, it tends not to know the types. E.g. in AMD, the following code would make sense:
but this leaves
$
with the typeany
(and noImplicitAny would complain about this). The options to handle this right now are:any
explicit.While I've describe the situation for AMD, my understanding is that other forms of async module loading (such as conditional
require()
calls in commonjs) suffer the same problems.note: unlike #3100 I am neither suggesting new syntax, or that typescript should handle loading async code in any way; I would just like to see it be able to strongly type such code as it already handles ES6-style imports, and leave the implementation details of module loading to actual module loaders like node.js or requirejs.
The text was updated successfully, but these errors were encountered: