TypeScript Version: 2.2.1
I've just started with Typescript and ES6/ES7 features and have run into the following case where I'm unable to enforce type-safety with generators.
I'm using generators in a context where the return value of the yield statement (the injected value from generator.next(injected)) has a known type interface. I've managed to enforce this contract by extending IterableIterator:
interface TypedIterableIterator<T, N> extends IterableIterator<T> {
next(value?: N): IteratorResult<T>;
}
However, Typescript is still unable to narrow down the type of injectedNum.
function* yieldNumber(num: number): TypedIterableIterator<number, number> {
let injectedNum = yield num; // has inferred type `any`
}
function test() {
let numYielder = yieldNumber(2);
numYielder.next('give me type-safety'); // successfully fails to compile
}
The only workaround I've found so far is to manually annotate the injected value and cross my fingers that I didn't use the wrong type.
{
let injectedNum: number = yield num;
// type-safe from here on... almost
}
This is a very simple use case, but my actual use case is with redux-saga, which heavily uses generators. Example code:
let returnValue = yield call(callback); // return value type of `callback` is lost
@ssynix this comment and this answer, both from #2983 may interest you. You might also want to check out the discussion in #2873.
Thanks for the links! I like the term "generator return type propagation". Couldn't figure out the right set of keywords to look up this topic earlier.
I'm going to close this since it's clearly a duplicate of what's being discussed in the mentioned links.
Most helpful comment
@ssynix this comment and this answer, both from #2983 may interest you. You might also want to check out the discussion in #2873.