ember-cli-typescript: TypeScript hangs with Promise.all(array) (With ArrayPrototypeExtensions)
Which package(s) does this problem pertain to?
- @types/ember
- @types/ember__string
- @types/ember__polyfills
- @types/ember__object
- @types/ember__utils
- @types/ember__array
- @types/ember__engine
- @types/ember__debug
- @types/ember__runloop
- @types/ember__error
- @types/ember__controller
- @types/ember__component
- @types/ember__routing
- @types/ember__application
- @types/ember__test
- @types/ember__service
- @types/ember-data
- @types/rsvp
- @types/ember-test-helpers
- @types/ember-testing-helpers
- Other
- I don’t know
What are instructions we can follow to reproduce the issue?
A small repo demonstrating a slow-down combining Promise.all while having interface Array<T> extends Ember.ArrayPrototypeExtensions<T> {}. Created it with as few moving parts as possible, so there is basically no code nor an ember app.
git clone git@github.com:mogstad/typescript-ember-slow-example.git
cd typescript-ember-slow-example
npm install
npm start
Now about that bug. What did you expect to see?
I expected the TypeScript code to be compiled swiftly.
What happened instead?
Running it on TS 3.0.3 takes 45 seconds, and 3.1.1 takes 8 minutes. We’re only seeing this issue using @types/ember >= 3.
Workarounds
We’ve found a few workarounds, by either defining the generic type of Promise.all<T> (and its friends). (Same issue if using rsvp)
let items = await Promise.all<string>(promises);
Or only extending MutableArray<T> instead of ArrayPrototypeExtensions, we’re not using anything in the Observable interface.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 23 (16 by maintainers)
Trying to spend a bit of time digging into this today. Will report what I find!
On my to-do list for most likely next week to get a solid repro so I can help the TS team chase down the root of this regression.
Just keep deleting surrounding code until you get a reasonable build time and build back up - maybe try to see what array extensions trigger it. @sanders_n might know more.
@danielrosenwasser just raising this for your info; I’m going to try to have a minimal repro of some sort next week filed as a bug on the TS repo on both the basic compile time issues and the major 3.1 regression; any pointers as to the best way to get the info you all need for that would be 💯.
We worked around this in
ember-osf-web(as @mogstad mentioned, but also includingCopyable).I did some playing around with this over the holiday break. It seems to be related to the conditional types in
UnwrapComputedPropertyGetter. It does not seem to be theinfer(I took it out and same result) but when I change the conditionals to hard-coded types, it compiles fast.Default types:
Remove
infer(e.g. hard-codestringinstead of inferred genericU):Remove conditional (e.g.
type UnwrapComputedPropertyGetter<T> = string;):I also found that compile time is dependent on the number of usages of
UnwrapComputedPropertyGetter. If I start removing usages in@types/ember__object/observable.d.ts:Remove
get:Also remove
getWithDefault:Also remove
cacheFor:Interestingly, removing
getProperties(which usesUnwrapComputedPropertyGetters, which usesUnwrapComputedPropertyGetter) had very little affect on compile time:Remove
getProperties:Same here. Would label this as a bug, as it makes development unbearable.
Commenting out the line
interface Array<T> extends Ember.ArrayPrototypeExtensions<T> {}intypes/package-name/index.d.ts“fixes” the problem, though it leads to other problems obviously…Ok, this is bizarre! Apparently, order matters. I’ll explain.
For https://github.com/mogstad/typescript-ember-slow-example
Using tsc 3.2.4, I get:
If I go into
node_modules/@types/ember__object/observable.d.tsand move the definitions forgetPropertiesandsetProperties(that use the mapped typesUnwrapComputedPropertyGettersandUnwrapComputedPropertySetters) to be the last things in the interface (so that they are defined after everything that usesUnwrapComputedPropertyGetterandUnwrapComputedPropertySetter), I get:I discovered this accidentally while creating a minimal repro (which I’ll post shortly).