Skip to content

Generator .throw() causes a "Object is possibly 'undefined'" error during compilation with strictNullChecks is enabled #14431

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

Closed
dsole opened this issue Mar 3, 2017 · 3 comments

Comments

@dsole
Copy link

dsole commented Mar 3, 2017

TypeScript Version: 2.1.1

Code

// A *self-contained* demonstration of the problem follows...
function* myGen() {
  yield "foo";
}

let gen = myGen();

gen.throw(new Error("err"));

Compiled with the command
tsc --strictNullChecks --target ES6 example.ts

Expected behavior:
Compilation passes successfully.

Actual behavior:
example.ts(8,1): error TS2532: Object is possibly 'undefined'.

The error is on the gen.throw() line.
I have already tried putting undefined checks, assigning a local variable, trycatch blocks etc in the code but the error persists.

@dsole
Copy link
Author

dsole commented Mar 3, 2017

The error is resolved if I do wrap the gen.throw() line with a check for gen.throw

if (gen.throw) {
  gen.throw(new Error("err"));
}

Is there a valid case where the throw function would not exist on a generator ?

@dsole dsole closed this as completed Mar 3, 2017
@dsole
Copy link
Author

dsole commented Mar 3, 2017

I'll raise this as a question on SO rather than a bug here.
Now that I see that the Iterator declaration has the throw and return functions marked as optional.

interface Iterator<T> {
    next(value?: any): IteratorResult<T>;
    return?(value?: any): IteratorResult<T>;
    throw?(e?: any): IteratorResult<T>;
}

@rclmenezes
Copy link

rclmenezes commented Feb 1, 2018

I dislike this behavior in TypeScript. All generators can raise an exception and all of them do return something.

Instead, why not make generators return a new interface that extends Iterator? This way, we can make return and throw required fields:

interface GeneratorIterator<T> extends IterableIterator<T> {
    return(value?: any): IteratorResult<T>;
    throw(e?: any): IteratorResult<T>;
}

True, the ECMA2015 schema says:

A Generator object is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

However, I'd argue that an extension of Iterator still conforms to Iterator!

This change would be less confusing for newcomers using strictNullChecks. Currently, you have to do a hack like:

const iter = gen();
if (iter.throw) {
    iter.throw();
} 

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants