Skip to content

String union types narrowed to falsy should narrow string to "" #45329

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

Open
JoshuaKGoldberg opened this issue Aug 5, 2021 · 4 comments
Open
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@JoshuaKGoldberg
Copy link
Contributor

JoshuaKGoldberg commented Aug 5, 2021

Bug Report

🔎 Search Terms

string truthy falsy narrow literal empty

🕗 Version & Regression Information

  • This is a crash
  • This changed between versions ______ and _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about narrowing
  • I was unable to test this on prior versions because _______

⏯ Playground Link

Playground link with relevant code

💻 Code

let value = Math.random() > 0.5 && "Some Name";

if (!value) {
  value; // Type: false | string, but should be false | ""
}

🙁 Actual behavior

Inside the narrowed block, value should be false | "", because no other string value is falsy.

🙂 Expected behavior

It's the more general false | string instead.

This was a hard issue to search for; #41503, #33878, and #31156 seemed related but not duplicate to me.

Shoutout to RyanCavanaugh for sending me a code snippet that looked like this -- no good deed goes unpunished in the issue tracker 😄

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Suggestion An idea for TypeScript Experimentation Needed Someone needs to try this out to see what happens labels Aug 5, 2021
@RyanCavanaugh
Copy link
Member

This seems like a good idea. I'm wondering what it'd break; would love a draft PR so we could run it over real-world code to see.

@JoshuaKGoldberg JoshuaKGoldberg changed the title String union types narrowed to falsy should narrow string to to "" String union types narrowed to falsy should narrow string to "" Sep 11, 2021
@JoshuaKGoldberg
Copy link
Contributor Author

@RyanCavanaugh following up since typescript-bot warned me this issue isn't accepted: does the non-negative results from the community code test suite and perf tests in the PR mean this looks like something you'd take in?

@ahejlsberg
Copy link
Member

ahejlsberg commented Oct 20, 2021

We've considered this one before, but we never implemented it because we can only narrow in the falsy case (narrowing in the truthy case would require negated types such as number & not 0). Other than the abstract example, are there real world scenarios this would enable?

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature and removed In Discussion Not yet reached consensus Experimentation Needed Someone needs to try this out to see what happens labels Feb 3, 2022
@JoshuaKGoldberg
Copy link
Contributor Author

Shoot sorry for missing this @ahejlsberg, it dropped off my radar. I've seen the occasional snippet of code that uses "" instead of null or undefined in unions of response types.

type Result = "ACK" | "ERR" | "";

declare const result: Result;

if (result) {
  // handle that a result was received
} else {
  // couldn't get a result
}

I don't have any examples that are open source, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants