Skip to content

Design Meeting Notes, 9/8/2021 #45790

Closed
Closed
@andrewbranch

Description

@andrewbranch

Await<T>, await, and Promise.all

#45350

  • 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.
  • Should await T produce Awaited<T>?
    • If the constraint is only primitive, you get T. Otherwise, you get Awaited<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 return unknown, 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 {} or unknown, 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 that extend Promise<number>. It’s weird. They would confuse the heck out of themselves.
    • Verdict: await T only produces Awaited<T> if your constraint is:
      • any
      • unknown
      • {}
      • object

Allow type parameter defaults in JSDoc tags

#45483

  • 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions