Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]stricter Generators: T not in scope #32507

Closed
kgtkr opened this issue Jul 22, 2019 · 5 comments
Closed

[Bug]stricter Generators: T not in scope #32507

kgtkr opened this issue Jul 22, 2019 · 5 comments
Assignees
Labels
Bug A bug in TypeScript Design Limitation Constraints of the existing architecture prevent this from being fixed Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@kgtkr
Copy link

kgtkr commented Jul 22, 2019

TypeScript Version: 3.6.0-dev.20190720

Search Terms:
Generators

Code

function* foo(): {
  next<T>(x: T): IteratorResult<void, void>;
} {
  // x: T
  const x = yield;
}

Expected behavior:
It is necessary to discuss how it should work

Actual behavior:
x: T

Related Issues:
#30790 #31639

@kgtkr
Copy link
Author

kgtkr commented Jul 22, 2019

other example

code

function* foo(): {
  next<T>(x: T): IteratorResult<T, void>;
} {
  // x: T
  const x = yield 1;
}

Expected behavior

x: number

Actual behavior

x: T

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.

@kgtkr kgtkr changed the title stricter Generators: T not in scope Bug:stricter Generators: T not in scope Jul 23, 2019
@kgtkr kgtkr changed the title Bug:stricter Generators: T not in scope [Bug]stricter Generators: T not in scope Jul 24, 2019
@DanielRosenwasser DanielRosenwasser added the Bug A bug in TypeScript label Jul 24, 2019
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 3.6.1 milestone Jul 24, 2019
@falsandtru
Copy link
Contributor

This is #30790 (comment) and #32523.

@rbuckton
Copy link
Member

rbuckton commented Aug 3, 2019

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.

@rbuckton
Copy link
Member

rbuckton commented 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 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<T extends string>(value: T): IteratorResult<unknown, void>;
} { 
  // x is 'T extends string'
  const x = yield;
  x.charAt(0); // ok
}

@DanielRosenwasser, @RyanCavanaugh this seems like something that might warrant further discussion?

@falsandtru
Copy link
Contributor

falsandtru commented Aug 6, 2019

Anyway parametric iterator methods are useless without supporting Rank-2 types.

function* foo(): {
  next<T>(x: T): IteratorResult<T, void>;
} {
  // T is `undefined | number`.
  yield undefined; // Return type is `undefined | number`, not `undefined`.
  yield 1; // Return type is `undefined | number`, not `number`.
}

https://prime.haskell.org/wiki/Rank2Types

Overloading may help us but it also brings some inconveniences.

function* foo(): {
  next<T extends undefined>(x: T): IteratorResult<T, void>;
  next<T extends number>(x: T): IteratorResult<T, void>;
} {
  yield undefined; // Return type is `undefined`.
  yield 1; // Return type is `number`.
}

@rbuckton rbuckton added Design Limitation Constraints of the existing architecture prevent this from being fixed Working as Intended The behavior described is the intended behavior; this is not a bug labels Aug 9, 2019
@rbuckton rbuckton closed this as completed Aug 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Design Limitation Constraints of the existing architecture prevent this from being fixed Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants