Closed
Description
Await<T>
, await
, and Promise.all
- Can we remove overloads Promise.all overloads?
- Puppeteer breaks because they supplied explicit type arguments, likely because inference didn't work, but should work now.
- They can remove the type arguments assuming our inference is now correct
- Otherwise, use one type argument as a tuple instead of multiple type arguments
- Well, actually in this case inference wouldn’t work—at least one argument returns
any
, so the type argument serves as a cast - One
any
degenerates the whole inference?
- Would it be better to leave the overloads in, marking them as deprecated to give people a release to adjust?
- Does the deprecated overload surface well? Yes, have to scroll all the way down in quick info, but yeah
- Anders: would love to just get rid of them.
- Can we prepare a PR for puppeteer that works both before and after? Yes, seems possible.
allSettled
may also have an overload ladder? Nope, it's already fine.all
was the only one.
- Verdict: Let's try just getting rid of them and listen for feedback.
- Puppeteer breaks because they supplied explicit type arguments, likely because inference didn't work, but should work now.
- Should
await T
produceAwaited<T>
?- If the constraint is only primitive, you get
T
. Otherwise, you getAwaited<T>
. - Didn't break anything in user test suite
- But, it's possible someone has something like
interface Foo { method(): void } async function fn<T extends Foo>(x: T) { const y = await x; y.method(); // Should error, because we don’t know that an instantiation won’t also have a callable `then` }
- Wait, this was supposed to error but didn’t: possible bug in definition of conditional type evaluation or definition of
Awaited
?- This is expected - if
T
doesn't appear to have a.then
method, you really need to returnunknown
, but that's a non-starter for a lot of reasons - Well, this isn't ideal, but it's not a regression over current behavior, because today you just always get
T
- (This flaw actually makes it less breaky)
- So, is producing
Awaited<T>
even valuable if you don’t get errors on that? - We just have to acknowledge that this is a soundness hole, that we assume there won't be a
.then
method - Unless your constraint is
{}
orunknown
, our heuristic should be that this thing is not going to be Promise-like. If your constraint is some interface that doesn't look Promise-like already, we should just assume that there will never be an instantiation with a subtype of it that also happens to be Promise-like. - Nobody is actually writing stuff with sneaky random
then
methods or declaring interfaces thatextend Promise<number>
. It’s weird. They would confuse the heck out of themselves.
- This is expected - if
- Verdict:
await T
only producesAwaited<T>
if your constraint is:any
unknown
{}
object
- If the constraint is only primitive, you get
Allow type parameter defaults in JSDoc tags
- JSDoc signatures allow you to express type parameters and constraints, but not defaults for them
- PR also includes a separate fix for resolving to other type parameters in constraints, but that's orthogonal
- Syntax:
@template {string} [T="hello"]
- We parse this already, but throw it out
- Braces indicate optionality like function parameters
- No objections
- Need to turn on declaration emit for these JS tests to make sure it can serialize the defaults