- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.1k
Defer generic awaited type #35064
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
Defer generic awaited type #35064
Conversation
4855cc2    to
    f8e58ec      
    Compare
  
    | @typescript-bot test this | 
| The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. | 
1c8c527    to
    7f71fcd      
    Compare
  
    ad41b21    to
    62a1d57      
    Compare
  
    | @typescript-bot test this | 
| The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. | 
| Looks like most of that diff is just file number changing There is a few errors though at this location - which I think could be correct. Does that feel right? | 
| Relates to #35998 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The then method only needs to be assignable to Function.
        
          
                src/lib/es5.d.ts
              
                Outdated
          
        
      | // The undefined case is for strictNullChecks false, in which case | ||
| // undefined extends PromiseLike<infer U> is true, which would otherwise | ||
| // make Awaited<undefined> -> unknown. | ||
| type Awaited<T> = T extends undefined ? T : T extends PromiseLike<infer U> ? U : T extends { then(...args: any[]): any } ? unknown : T; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| type Awaited<T> = T extends undefined ? T : T extends PromiseLike<infer U> ? U : T extends { then(...args: any[]): any } ? unknown : T; | |
| type Awaited<T> = T extends undefined ? T : T extends PromiseLike<infer U> ? U : T extends { then: Function } ? unknown : T; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Works, thanks for your help! Done. ✔️
3e6abf1    to
    b48a356      
    Compare
  
    | The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. | 
| These baselines look alright to me - jablko#7 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not believe this is the correct solution to this problem.
| return typeAsAwaitable.awaitedTypeOfType = type; | ||
| } | ||
|  | ||
| const promisedType = getPromisedTypeOfPromise(type); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with this change. This completely removes support for recursively unwrapping a non-native promise, which is a core capability of await and our type-system support for it which has existed since the feature was added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a non-native promise resolve to another promise? If not, then await isn't recursive and I think this change is safe?
If it can, then I concede that implies a recursive awaited solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, non‑native promises can resolve to an object with a .then function property, which await will resolve recursively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that violate Promises/A+?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jablko: non-native promise-like implementations aren't all guaranteed to be Promise/A+. In the past, JQuery's defer created something promise-like (i.e. it has a callable then that accepted fulfill/reject callbacks), but it did not recursively unwrap. This is why native await and native Promise both recursively unwrap (to defend against non-Promise/A+-compliant promise-likes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
await is recursive for non-native promises. In https://tc39.es/ecma262/#await, the value is passed to PromiseResolve which adopts the foreign promise and performs recursive unwrapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I concede that await is recursive for non-compliant promises. Does supporting non-compliant promises justify introducing a new kind of type?
There's only ever been incomplete support for non-compliant promises in TypeScript. TypeScript's native promise type hasn't recursively unwrapped non-compliant promises until now. For native and A+-compliant promises, await isn't recursive because they can't be nested.
Is a non-compliant promise more likely actually an error? Supporting non-compliant promises can be error prone, masking what are otherwise errors.
7da42e8    to
    034a6fc      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there are outstanding comments on this PR, so I'm going to request changes to help me track our PR backlog.
340aaa9    to
    d802893      
    Compare
  
    5cb7c3f    to
    49ad9c9      
    Compare
  
    You can include es2015.promise.d.ts without es2015.iterable.d.ts. It was moved to es2015.promise.d.ts in microsoft#31117
| This PR hasn't seen any activity for quite a while, so I'm going to close it to keep the number of open PRs manageable. Feel free to open a fresh PR or continue the discussion here. | 
Roll up
#33062, #33074,#33103,#33105, #33707 and #35284Fixes
#27711Fixes #22469
Fixes #28427
Fixes
#30390Fixes #31722
Fixes #33559
Fixes #33562
Fixes #33752
Fixes
#34924Fixes #34937
Fixes
#35136Fixes
#35258@typescript-bot test this
@typescript-bot run dt
@typescript-bot user test this