A valid use case for null is when you want to iterate over object properties and do some logic if corresponding values are empty. You usually don't want to write things like typeof string && "". What about numbers? What about booleans? Angular for instance uses it in its Forms Module. If a non-string field is empty, its value is null. If you reset any field value its default is null. So to me null is absolutely legit and not synonymous to undefined.
You usually don't want to write things like typeof string && ""
That doesn't make much sense for me. If something can be either string | undefined, then adding | null to the mix doesn't help much here. You end up having to test for yet another type, when you could just keep it simple.
constvalidate=([key,value])=>`${key} is ${value??"nullish"}`;
Which would work exactly the same for both null and undefined. What's the advantage of null over undefined here?
And about the argument of "Angular uses this in its Forms Module", just because a module/library/package uses null, that doesn't mean that you need to use null all over your app as well. Not to mention that if a non-string field is empty, it could be undefined as well, same if you reset it, is just an implementation detail of that forms module, which doesn't mean you need to use null in places where you're not interacting with that particular module.
Good points! My examples were not that good. Still, in some other place of my program I might want to directly access the object property like foo.bar and if it is undefined how can I be sure that the property even exists? I mean they are semantically different and have slightly different behaivior and I embrace them both as features of the language. You are correct in your wordplay, you don't need null, but I want to extend this and say that you may want it. For consistency, readabitity, because of business requirement or for whatever other reason. This is not a "goto"-situation. If you choose wisely your code will only get better. Like in Typescript there are types any and unknown which are in many cases interchangeable without any side effects, but... unknown is safer and sometimes you really need any.
You might be one of the first devs to comment here with the "opposite view" but you actually understood the post π€£ ... Indeed, the idea is that you don't need null and you can use undefined to express the same things better, but if there's a library that only works with null, then you have to use it there. The main idea is that we shouldn't default to null and just use it when is actually necessary. Some folks think is necessary to make a distinction between null and undefined and I (and many other devs) disagree with this because they both represent a "no-value" or "nullish", but that doesn't mean "you should never use null", that only means "you should use it when is actually necessary", like APIs or libs that only work with null.
About any vs unknown, I might write a "you don't need any" showing how you can use unknown everywhere, safely, even if you want to be lazy as you'll be using just any βΊοΈ
I might be wrong, of course, but I am still not as convinced as you are. They are simply different and we would probably have quite heated debates regarding some special cases if we were working in same team. And I would also install a swear jar for such words like "nullish" or "falsy". My code is strict and explicit af π
Although, to be completely honest, I also have to admit that we really did forbid null in our previous project and mapped all null values as undefined in all our API responses. Didn't regret this decision, in our case (with good models) undefined worked as "empty value" really good, felt natural and the only places where null was really inavoidable were API and Angular forms.
Btw, I have a good example where you really need any. It's JSON:API standard which defines one of the fields as object, so the best you can do on the most abstract level (before any extensions with type narrowing) is something like Record<string, any>.
But you could also do Record<string, unknown>, which is like saying: I know this is an object, I just don't know the type of the properties inside of it ... way better than having any and accidentally calling a method or passing it to a function without first checking what that is. I see unknown as strict any, you can't use it unless you first figure out what it is. And I love it.
I also code pretty strictly and I still see not benefit using null at all (unless, as we said already, I'm interacting with something that needsnull). And I share that experience you had, of migrating codebases to only using undefined, or having that no-null ESLint rule, and the best thing about that experience is that not only me, but nobody in those teams missed null (that's also why I shared that talk given by Douglas Crockford, because he had the same experience, years ago).
You're not stupid! I used to use any quite a lot before unknown was introduced, so it's ok if you're still checking before using it. The main difference is that unknown forces you to do that check, but if you still do it is ok!
The thing is that today I really never use any (except for Angular and such). Absolutely forbidden! But I also wrote the implementation for jsonapi before I learnd unknown. So... π€·π
A valid use case for null is when you want to iterate over object properties and do some logic if corresponding values are empty. You usually don't want to write things like typeof string && "". What about numbers? What about booleans? Angular for instance uses it in its Forms Module. If a non-string field is empty, its value is null. If you reset any field value its default is null. So to me null is absolutely legit and not synonymous to undefined.
That doesn't make much sense for me. If something can be either
string | undefined, then adding| nullto the mix doesn't help much here. You end up having to test for yet another type, when you could just keep it simple.This two behave exactly the same:
So
validatethere could be implemented like this:Which would work exactly the same for both
nullandundefined. What's the advantage ofnulloverundefinedhere?And about the argument of "Angular uses this in its Forms Module", just because a module/library/package uses
null, that doesn't mean that you need to usenullall over your app as well. Not to mention that if a non-string field is empty, it could beundefinedas well, same if you reset it, is just an implementation detail of that forms module, which doesn't mean you need to usenullin places where you're not interacting with that particular module.Good points! My examples were not that good. Still, in some other place of my program I might want to directly access the object property like foo.bar and if it is undefined how can I be sure that the property even exists? I mean they are semantically different and have slightly different behaivior and I embrace them both as features of the language. You are correct in your wordplay, you don't need null, but I want to extend this and say that you may want it. For consistency, readabitity, because of business requirement or for whatever other reason. This is not a "goto"-situation. If you choose wisely your code will only get better. Like in Typescript there are types any and unknown which are in many cases interchangeable without any side effects, but... unknown is safer and sometimes you really need any.
You might be one of the first devs to comment here with the "opposite view" but you actually understood the post π€£ ... Indeed, the idea is that you don't need
nulland you can useundefinedto express the same things better, but if there's a library that only works withnull, then you have to use it there. The main idea is that we shouldn't default tonulland just use it when is actually necessary. Some folks think is necessary to make a distinction betweennullandundefinedand I (and many other devs) disagree with this because they both represent a "no-value" or "nullish", but that doesn't mean "you should never usenull", that only means "you should use it when is actually necessary", like APIs or libs that only work withnull.About
anyvsunknown, I might write a "you don't need any" showing how you can useunknowneverywhere, safely, even if you want to be lazy as you'll be using justanyβΊοΈI might be wrong, of course, but I am still not as convinced as you are. They are simply different and we would probably have quite heated debates regarding some special cases if we were working in same team. And I would also install a swear jar for such words like "nullish" or "falsy". My code is strict and explicit af π
Although, to be completely honest, I also have to admit that we really did forbid null in our previous project and mapped all null values as undefined in all our API responses. Didn't regret this decision, in our case (with good models) undefined worked as "empty value" really good, felt natural and the only places where null was really inavoidable were API and Angular forms.
Btw, I have a good example where you really need any. It's JSON:API standard which defines one of the fields as object, so the best you can do on the most abstract level (before any extensions with type narrowing) is something like Record<string, any>.
But you could also do
Record<string, unknown>, which is like saying: I know this is an object, I just don't know the type of the properties inside of it ... way better than havinganyand accidentally calling a method or passing it to a function without first checking what that is. I seeunknownas strictany, you can't use it unless you first figure out what it is. And I love it.I also code pretty strictly and I still see not benefit using
nullat all (unless, as we said already, I'm interacting with something that needsnull). And I share that experience you had, of migrating codebases to only usingundefined, or having thatno-nullESLint rule, and the best thing about that experience is that not only me, but nobody in those teams missednull(that's also why I shared that talk given by Douglas Crockford, because he had the same experience, years ago).You're right. And I am stupid. Of course, unknown can be narrowed same as any. Simply forgot that.
You're not stupid! I used to use
anyquite a lot beforeunknownwas introduced, so it's ok if you're still checking before using it. The main difference is thatunknownforces you to do that check, but if you still do it is ok!The thing is that today I really never use any (except for Angular and such). Absolutely forbidden! But I also wrote the implementation for jsonapi before I learnd unknown. So... π€·π
That's what happen to folks like us that were in this TypeScript game for a long time x'D