Skip to content

Design Meeting Notes, 4/30/2024 #58417

Open
@DanielRosenwasser

Description

@DanielRosenwasser

TReturn and TYield for Iterators and Other Types

#58243

  • TReturn is the type of values returned by a generator.
  • TYield is the type of values yielded by a generator.
  • When we added these, we only added them to certain types like IteratorResult
    • Since then, we have a PR that adds type parameters to Iterator, IterableIterator, AsyncIterable, etc.
    • What this has meant since then was that if you ever try to grab value off of most IteratorResults, then you'll get any.
      • Good as a fall-back, but usually not what people want.
  • Changing this is a breaking change - so how can we avoid breaks?
    • First, each of these types should have a default value for TReturn and TYield that is any.
      • But when a user writes Iterator<number>, TypeScript should preserve that type as-is.
    • What is the level of breakage as is?
      • Almost every case is an example of the type system not knowing that size > 0 implies value is not undefined.
      • There's also a lot of breakage around DefinitelyTyped's ExpectType and ExpectError utility types.
  • Several new errors introduced. Previously, people expecting .next() to return a T now get T | void.
    • e.g. if (something.size === 1) { something.values().nexT().value.getTasks(); }
    • Why is it void and not undefined?
      • Should it be undefined?
      • We really don't want to relitigate all the issues around non-returning functions returning void instead of undefined.
      • It's possible we carve things out for generators.
    • Should we allow postfix ! to get rid of void?
  • How many upvotes does resolution for this issue have?
    • Old issue had around 15 upvotes.
    • This is so breaky that most of this has to go under a switch.
  • What happens if we don't do this?
    • People trying to thread these into the built-in iterator types.
    • If you have a generator, you can now write myGenerator().map(x => x * x) and you want the TReturn preserved.
  • If the worst thing you have to do is add a !, is that so bad?
  • Feel like there should be an approach where this is flagged.
    • Could be like strictBindCallApply.
    • We fret about breaks for much more widely-requested features.
    • But the people it breaks are using iterators, probably want to use the feature.
    • The flag that this conceptually aligns with is noUncheckedIndexedAccess.
      • Ah yes, .next(), the famous indexed access syntax.
      • Okay, fine, a separate flag with an equally bad name (noUncheckedIteratorAccess or noUncheckedIteratorResult).

tsc --init Updates?

  • We noticed tsc --init adds "module": "commonjs" - which our docs said to never ever ever do.
  • Okay, what else do we need to fix in --init?
  • Ryan asked on Twitter what people would like to change.
  • People said lots of stuff
    • Big one that resonates: remove the wall of text comments
  • Are we okay wiht tsc --init generating a file today?
    • Uh yes.
  • Okay, that's a good start.
  • What else?
    • Make it minimal
    • People seem opposed to interactive.
  • Okay, what are things that need to be hashed through?
    • target: esnext?
    • module - node16 or bundler?
    • verbatimModuleSyntax?
    • skipLibCheck?
    • We need to hash through these.
  • Should we still have some comments on 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