You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
main.ts:5:19 - error TS2322: Type '1' is not assignable to type 'T'.
'1' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
5 const x = yield 1;
~
Found 1 error.
Your second example looks like it should be an error. If your generator return type says the definition for next is <T>(x: T) => IteratorResult<T, void>, then you should only be yielding the thing that was sent with next, however that's not how generators work.
As odd as it looks, I'm not even certain that the first example is really an error. We contextually type the result of yield as the type of the argument that is passed to next. The only other thing we could do here is possibly make the result unknown or any, but T is actually better here (especially if T had a constraint):
function*foo(): {next<Textendsstring>(value: T): IteratorResult<unknown,void>;}{// x is 'T extends string'constx=yield;x.charAt(0);// ok}
Anyway parametric iterator methods are useless without supporting Rank-2 types.
function*foo(): {next<T>(x: T): IteratorResult<T,void>;}{// T is `undefined | number`.yieldundefined;// Return type is `undefined | number`, not `undefined`.yield1;// Return type is `undefined | number`, not `number`.}
Overloading may help us but it also brings some inconveniences.
function*foo(): {next<Textendsundefined>(x: T): IteratorResult<T,void>;next<Textendsnumber>(x: T): IteratorResult<T,void>;}{yieldundefined;// Return type is `undefined`.yield1;// Return type is `number`.}
Activity
kgtkr commentedon Jul 22, 2019
other example
code
Expected behavior
x: numberActual behavior
x: T[-]stricter Generators: `T` not in scope[/-][+]Bug:stricter Generators: `T` not in scope[/+][-]Bug:stricter Generators: `T` not in scope[/-][+][Bug]stricter Generators: `T` not in scope[/+]falsandtru commentedon Jul 25, 2019
This is #30790 (comment) and #32523.
rbuckton commentedon Aug 3, 2019
Your second example looks like it should be an error. If your generator return type says the definition for
nextis<T>(x: T) => IteratorResult<T, void>, then you should only be yielding the thing that was sent withnext, however that's not how generators work.rbuckton commentedon Aug 3, 2019
As odd as it looks, I'm not even certain that the first example is really an error. We contextually type the result of
yieldas the type of the argument that is passed tonext. The only other thing we could do here is possibly make the resultunknownorany, butTis actually better here (especially ifThad a constraint):Daniel Rosenwasser (@DanielRosenwasser), Ryan Cavanaugh (@RyanCavanaugh) this seems like something that might warrant further discussion?
falsandtru commentedon Aug 6, 2019
Anyway parametric iterator methods are useless without supporting Rank-2 types.
https://prime.haskell.org/wiki/Rank2Types
Overloading may help us but it also brings some inconveniences.