Open zojize opened 3 years ago
Wow, I just came here to raise this, only to find this issue created only a couple weeks ago! Crazy timing! 😮
In any case, the use-cases presented in #32523 also require (or rather, are partially enabled by) this feature. Specifically, those use-cases are:
redux-saga
's Sagasmobx-state-tree
's Asynchronous Actionsdo
syntax for sequencing monadic actions (example)Thinking a bit about type inference...
I imagine it would be straightforward for simple cases, right?
For example, the inferred return type of
function* foo() {
yield 0;
yield 1;
}
would presumably be either *[0, 1]
or *[number, number]
(to borrow SIGUSR97's syntax).
As soon as loops are involved though, it looks like things get much more fun! 😅
For example, what would the inferred return type of
function* foo() {
for (let n = 0; n < 5; n += 1) {
yield n;
}
}
be?
I'm guessing something like *number[]
?
Let's get more complex though. What would the inferred return type of
function* foo() {
yield 0;
for (let n = 1; n < 4; n += 1) {
yield n;
}
yield 4;
}
be?
Maybe something like *[0, ...*number[], 4]
or *[number, ...*number[], number]
?
When you start thinking about nested loops, things look a bit scary. Generics and conditionals further terrify me. 😱
@rbuckton You seem to be Generator Man; got any thoughts on this? 😜
Can we get an official comment explaining why this isn't higher priority? I want to destructure a class instance as if it was a tuple. I define 0
and 1
getters on the prototype and both have different type signatures.
Arrived here with the exact same use-case and issue as @zojize; vector types and the canvas.
Feels like I should be able to manually specify something like TupleGenerator<[number, number], ...>
It could de-sugar to something like below;
class Vector2 {
x:number;
y:number;
// public* [Symbol.iterator]: TupleGenerator<[number, number], void, unknown> { // <--desired syntax
// yield this.x;
// yield this.y;
// }
public* [Symbol.iterator]: Generator<number, void, unknown> { // de-sugared
yield this.x;
yield this.y;
}
public toTuple():[number, number]{ // de-sugared
return [this.x, this.y]
}
}
let a = new Vector2(1,2);
// ctx.moveTo(...a); // <-- desired syntax
ctx.moveTo(...a.toTuple()); // de-sugared
Static type inference for *[Symbol.iterator]
is obviously impossible for complex iterators... but why not have this for manually specified types :)
@thehappycheese I submitted a PR based on your suggestion, let me know what you think 😃
Search Terms
Suggestion
Express a fixed-length generator.
Use Cases
Examples
stackoverflow question
Right now, the code above produces the correct behavior. However, typescript doesn't not recognize how many arguments is passed to
ctx.moveTo
andctx.lineTo
therefore it warns me about it.My Implementation
There could be an tuple-like syntax for generators as well, for example:
With this syntax, typescript recognizes how many argument is deconstructed by the spread operator, and knows its a generator with the prepending
*
.Checklist
My suggestion meets these guidelines: