Skip to content

Inferred never values don't properly type guard #60185

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
a-non-a-mouse opened this issue Oct 10, 2024 · 7 comments
Closed

Inferred never values don't properly type guard #60185

a-non-a-mouse opened this issue Oct 10, 2024 · 7 comments

Comments

@a-non-a-mouse
Copy link

πŸ”Ž Search Terms

never type guard

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about type guarding

⏯ Playground Link

https://www.typescriptlang.org/play/?noUncheckedIndexedAccess=true&moduleResolution=99&target=99&module=199&exactOptionalPropertyTypes=true&ts=5.6.3#code/GYVwdgxgLglg9mABAExgUwBQEoBcixoBuaATogN4BQiNiJaUIJSYIANm4gIYDO+RpANyUAvpUqhIsBIhhhgpACLpsFarXqNmKFVmFjKyNBDZd6iCAh5READzzWScgOaIAPvnZthlGMEQYAIS2WGq0svJKuvritoKIAPQJdrJ81jAciAAOcDw8MABGbACenhzifgHBoVThqJh6orHxSSlgcADuFlxgAOQ2BWhlbEA

πŸ’» Code

function die(): never {
    return null as never;
}

function inferDie() {
    return die();
}

declare const x: string | null;

if (!x) {
    inferDie();
}

x; // x is still possibly null

if (!x) {
    die();
}

x; // x now can't be null

πŸ™ Actual behavior

Two functions that have "identical" signatures, () => never, are not acting the same

πŸ™‚ Expected behavior

I'd expect both of these to act the same way since, for everything I can see, TS sees their signatures as being identical.

Additional information about the issue

No response

@Andarist
Copy link
Contributor

as per #32695 :

  • 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.

Your inferDie has no explicit never return type so it's not treated as an assertion

@a-non-a-mouse
Copy link
Author

Yes, I realize the why, but there is no way whatsoever to tell what a function is going to do in this case without literally looking at the source of it.

TS shows that both are () => never. So if you look at a tool tip or whatnot in any editor, you have no idea what the code is actually going to do.

@a-non-a-mouse
Copy link
Author

I'd argue that this behavior is wrong, but alternatively tooling should be able to tell the difference. As far as I can tell, TS doesn't actually expose the difference.

@MartinJohns
Copy link
Contributor

MartinJohns commented Oct 10, 2024

The behavior is intentional, not wrong, and was done for performance reasons.

But it would probably be good to add this to the FAQ. And to the handbook, which is covered by #59930.

@a-non-a-mouse
Copy link
Author

Oh ffs, I'm done reporting issues to you guys. You make stupid ass decisions and then try to justify them. It's utterly pathetic.

@MartinJohns
Copy link
Contributor

Neither me nor Andarist are part of the TypeScript team. But you can be assured that the team does not make these decisions willy-nilly or out of spite, there's reasons behind them. They're not "stupid ass decisions", they're technical decisions with benefits and drawbacks.

And you're advised to check out the Code of Conduct. :-)

@a-non-a-mouse
Copy link
Author

Oh nooo, you're offended.

Like I give a single fuck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants