> I've come to see this ubiquitous string of symbols, ?? "", as the JS equivalent to .unwrap() in Rust Isn't this more like `unwrap_or`?
Abuse of the nullish coalescing operator in JS/TS
61–70 of 70 posts
Re: Abuse of the nullish coalescing operator in JS/TS
#62Earlier quoted context omitted.
Assuming assert existed, it would almost certainly be judging its value for being falsy , while the ?? operator judges its LHS for being nullish , which is a narrower category. For strings, this affects whether the empty string is acceptable or not.
> Assuming assert existed It's a function you could write for yourself and give it whatever semantics you feel is best. No changes to the language required for this one.
Re: Abuse of the nullish coalescing operator in JS/TS
#63There’s nothing wrong with using the ?? operator, even liberally. But in cases where 1) you don’t think the left side should be undefinable at all or 2) the right side is also an invalid value, you’re better off with an if-statement and handling the invalid case explicitly.
But I’ve used ?? thousands of times in my code in ways unrelated to 1) and 2).
Trivial example:
const numElements = arr?.length ?? 0
IMO this is fine if it’s not an important distinction between an array not existing and the array being empty, and gives you an easier to work with number type.
Re: Abuse of the nullish coalescing operator in JS/TS
#64Earlier quoted context omitted.
while this is nice, the type itself doesn't encode the logic (unlike refinement type) i think this would be really nice if validation libraries like zod returned branded types when they are validating non-comp-time types (like z.ipv4() should return some IPv4 branded type)
The type encodes the logic in the schema, it is absolutely a refinement as every parser is. Maybe you meant a comparison with dependent types? Now every time you will have to use a NonEmptyString255 as a type it has to be branded by passing through the constructor, so you can't pass a normal string to an API expecting it, and you get the error at type level. The logic is encoded in the schema itself, which you can cl…
i was suggesting the result of zod parse is a type that shows how it’s been refined
however, .ipv4().parse(“..”) returns a type “string”
Re: Abuse of the nullish coalescing operator in JS/TS
#65Early errors are good, but I think the author overstates the importance of filtering out empty strings --- I disagree that erroring out when the app doesn't have ALL the data is the best course of action. I imagine it depends a bit on the domain, but for most apps I've worked on it's better to show someone partial or empty data than an error. Often the decision of what to do when the data is missing is best left up t…
Sure, but in that case string | undefined is the correct type, and turning it into string | “” isn’t helping anybody. It’s the difference between: if (fooBarDisplayName) { show div } And: if (foobarDisplayName && foobarDisplayName.length > 0) { show div } Ultimately, type systems aren’t telling you what types you have to use where - they’re giving you tools to define and constrain what types are ok.
My example is we want to skip the div if empty or undefined. We can't throw on assignment so we leave it as as string|undefined.
When we go to display, we have to check if the string is empty anyway, right? What if it's empty in the DB or API response?
No matter what the display-component is doing something to prevent showing the empty string.
` if(fooBarDisplayName.length) { show div } `
or
` if(fooBarDisplayName?.length) { show div } `
I'm not sure what we gain by leaving it as `string|undefined`
---
If there was a "NonEmptyString" type maybe I could see where you're coming from.
I guess you could argue treating `string` like a `NonEmptyString` type seems error prone. The compiler can't verify you've done the check. At some point someone will set a string when it's empty or not do the necessary check.
You'd want a separate non-string type to make sure it's actually been parsed
Re: Abuse of the nullish coalescing operator in JS/TS
#66Earlier quoted context omitted.
The type encodes the logic in the schema, it is absolutely a refinement as every parser is. Maybe you meant a comparison with dependent types? Now every time you will have to use a NonEmptyString255 as a type it has to be branded by passing through the constructor, so you can't pass a normal string to an API expecting it, and you get the error at type level. The logic is encoded in the schema itself, which you can cl…
oh i guess you use zod in every single part of your application? not just api level. i was suggesting the result of zod parse is a type that shows how it’s been refined however, .ipv4().parse(“..”) returns a type “string”
string
type nonEmptyStr = string & NonEmpty
type ipv4Str = string & IPv4
it’s not obvious how you’d automatically determine ipv4Str is also a nonEmptyStr, since the types themselves are just labels, they don’t store the refinements at type level
Re: Abuse of the nullish coalescing operator in JS/TS
#67It seems Rust's unwrap is the exact opposite of ?? "". It throws an error instead of using a fallback value, which is exactly what the author suggests instead of using ?? "".
As you, and many others, have pointed out, `?? ""` does not do what `.unwrap` does. `unwrap_or_default` would have been a better comparison for what it actually does. What I tried, and failed, to communicate, was that both can be used to "ignore" the unwanted state, `None` or `undefined`.
I guess the rust equivalent to what I would like to see is `nullable_var?`, and not unwrap as that will panic. That would be equivalent to the `?? throw new Error` feature mentioned further up in the comments.
Re: Abuse of the nullish coalescing operator in JS/TS
#68I cannot tell if the author would agree with this, but here’s my take: There’s nothing wrong with using the ?? operator, even liberally. But in cases where 1) you don’t think the left side should be undefinable at all or 2) the right side is also an invalid value, you’re better off with an if-statement and handling the invalid case explicitly. But I’ve used ?? thousands of times in my code in ways unrelated to 1) and…
Re: Abuse of the nullish coalescing operator in JS/TS
#69> I've come to see this ubiquitous string of symbols, ?? "", as the JS equivalent to .unwrap() in Rust Isn't this more like `unwrap_or`?
Re: Abuse of the nullish coalescing operator in JS/TS
#70> Personally, I've come to see this ubiquitous string of symbols, ?? "", as the JS equivalent to .unwrap() in Rust It's funny you bring this up because people opposed to `.unwrap()` usually mention methods like `.unwrap_or` as a "better" alternative, and that's exactly the equivalent of `??` in Rust.
Semantically the two are kind of opposite; the similarity is that they're the lowest-syntax way in their respective languages to ignore the possibility of a missing value, and so get overused in situations where that possibility should not be ignored, leading to bugs.