Design Meeting Notes, 4/30/2024
DanielRosenwasser opened this issue · comments
Daniel Rosenwasser commented
TReturn
and TYield
for Iterators and Other Types
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 mostIteratorResult
s, then you'll getany
.- Good as a fall-back, but usually not what people want.
- Since then, we have a PR that adds type parameters to
- Changing this is a breaking change - so how can we avoid breaks?
- First, each of these types should have a default value for
TReturn
andTYield
that isany
.- But when a user writes
Iterator<number>
, TypeScript should preserve that type as-is.
- But when a user writes
- What is the level of breakage as is?
- Almost every case is an example of the type system not knowing that
size > 0
impliesvalue
is notundefined
. - There's also a lot of breakage around DefinitelyTyped's
ExpectType
andExpectError
utility types.
- Almost every case is an example of the type system not knowing that
- First, each of these types should have a default value for
- Several new errors introduced. Previously, people expecting
.next()
to return aT
now getT | void
.- e.g.
if (something.size === 1) { something.values().nexT().value.getTasks(); }
- Why is it
void
and notundefined
?- Should it be
undefined
? - We really don't want to relitigate all the issues around non-returning functions returning
void
instead ofundefined
. - It's possible we carve things out for generators.
- Should it be
- Should we allow postfix
!
to get rid ofvoid
?
- e.g.
- 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 theTReturn
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
ornoUncheckedIteratorResult
).
- Ah yes,
- Could be like
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
orbundler
?verbatimModuleSyntax
?skipLibCheck
?- We need to hash through these.
- Should we still have some comments on defaults?
- Maybe.
- Ryan also wrote a wizard, someone else wrote something too.
Martin Johns commented
Related: #46150