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

Yielding an assertion function call does not narrow the asserted type #55205

Closed
WilcoKruijer opened this issue Jul 30, 2023 · 3 comments
Closed
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@WilcoKruijer
Copy link

Bug Report

πŸ”Ž Search Terms

generator, yield, assertion function

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about assertion functions and generators.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

 function * testFunc() {
    type SomeType = {a: number};

    let count = 0;
    function assertAThing(obj: unknown): asserts obj is SomeType {
        // don't care about the impl
        count++;
    }

    const bla: unknown = {a: 3};
    assertAThing(bla);

    // no type error here
    console.log(bla.a);

    const bla2: unknown = {a: 4};
    yield assertAThing(bla2);

    // bla2 is unknown, but should be SomeType as asserted by the assertAThing call.
    if (bla2.a !== 4) {
        throw new Error("bla2.a should be 4.");
    }

    if (count !== 2) {
        throw new Error("Count should be two.");
    }

    console.log("Javascript success")
 }

for (const item of testFunc()) {
    //
}

πŸ™ Actual behavior

The variable bla2 is still unknown even after passing it through the assertion function assertAThing.

πŸ™‚ Expected behavior

bla2 should be narrowed to be SomeType like bla1.

Workaround

We are effectively yielding void since assertion functions cannot return anything. This means there is a simple workaround:

assertAThing(bla2);
yield;
@MartinJohns
Copy link
Contributor

This is not a bug as per #32695:

A function call is analyzed as an assertion call or never-returning call when

  • the call occurs as a top-level expression statement, and
  • the call specifies a single identifier or a dotted sequence of identifiers for the function name, and
  • each identifier in the function name references an entity with an explicit type, and
  • the function name resolves to a function type with an asserts return type or an explicit never return type annotation.

@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Aug 1, 2023
@RyanCavanaugh
Copy link
Member

This doesn't seem like something you would likely (ever?) actually do in real code, and making new CFA graph nodes slows down everything else.

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Aug 4, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a Defect This behavior is one of several equally-correct options
Projects
None yet
Development

No branches or pull requests

4 participants