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
Abandon null in favor of undefined
#42713
Comments
|
I 100% agree that null should be abandoned, but it has already been discussed here #16982 (comment) I think nothing has changed since then. |
Thanks, @evgeniyefimov, for pointing me to that discussion which I haven't been aware of. As @mhevery pointed out, it's a huge breaking change to migrate from |
|
Funny; I'd be using only Firstly, while I agree that there should be a convention, I don't think all instances of either can be replaced with one of those. As you said,
which, to me, means that For example, the way I see it, For example, I agree that Secondly, you suggest some strategies which I've seen people avoid with time, including myself.
This is a footgun whenever a falsy value should not be treated as To avoid thinking about
It's also easier to understand the intent behind I'm quite confused as your list then jumps to this example"
without even mentioning a simple |
In all my professional career I never had the need to distinguish between something "initialized with null" and something that has not been initialized. For me, this is semantically the same thing. Even more so, because when you receive Regardless, at runtime, it just doesn't matter if something "is null" or "is undefined". It's both semantically the same thing: i.e. "nothing". For example, you have been mentioning Concerning your "async" example, I would rather recommend to use an explicit value for indication of "LOADING" state, rather than overloading "undefined" with that semantic.
This is exactly how Map#get works! But rather than needlessly "initializing" values with
That's exactly why I've added the third rule:
Coming to your last argument:
Yes, I've been actively avoiding loose equality comparison with |
|
I also found that since constructor(@Optional() @Inject(API_ENDPOINT_URL) private apiUrl= '/api') {
console.log(apiUrl); // null
}Default parameters only work with undefined. |
|
The issue of |
|
While I appreciate the sentiment of having strict guidelines and usage patterns for |
@pkozlowski-opensource can you point me to a few examples where this distinction is relevant? I'm asking because I'm really curious and couldn't find such a use case until now :-) |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Feature Request
Relevant Package
Description
At the moment of writing this (June 2021), in the Angular code base, there seems to be no clear guideline for when to use
nulland when to useundefined. A brief search shows that (in the Angular code base starting from./packages) assignment tonull(= null, notice the leading space to avoid matching=== null) occurs 1448 times, and assignment to undefined (= undefined) can be found 1905 times. While it is understandable to accept and properly handle passednullvalues from the point of view of public api (because Angular is a framework after all and users should be able to use whatever value they like), it is not understandable (to me), whynullis used internally at all. This is problematic, because it makes it very easy for thenullvalue to bleed through Angular's public api (which it shouldn't!).(Imho) Nowadays, the type
nulljust shouldn't be used in modern TypeScript code any more. The reasons for that are simple:undefinedtype to a type definition via?character: e.g.myClassPropertyOrMethodParam?: number. Usingnullinstead just feels awkward (e.g.myClassPropertyOrMethodParam: number | null) and makes the code less readable. In that case you will end sooner or later addingundefined, too (e.g.myClassPropertyOrMethodParam?: number | null, some people even prefer to addundefinedexplicitly in that case to "improve readability"myClassPropertyOrMethodParam: number | null | undefined).undefinedis the natural default type of anything that has not been initialized.typeof null === 'object' // sadly true.Consider Brendan Eich's two-word suggestion: "Use undefined"
Example where
nullbleeds through Angular APIThere's one module where it particularly bothers me, that Angular uses
null, becausenullbleeds through. What I mean by "bleeding through" is, that thenulltype is exposed via API that is consumed by Angular users:The @angular/forms package assigns
nullas the default value to a form control! See here and here!Why is this a problem?
This is a serious problem (imho)! What Angular is doing here is very offensive! It is forcing its users (or say at least it's tricking its users below senior level, which could well be >80%) to include the
nulltype in their own API / interfaces, because it's just possible that a form control is in that state! This can make code more complicated than it has to be. It actively hinders people from trying to avoidnullinside their own code base. For example what I can see regularly in our code base are things like this:When I ask them why they've included
nullin their type, what I usually hear as an explanation is "because otherwise it would not have been compatible with Angular Forms API".To be clear: while adding
nulltosomeOptionalPropertyis no harm, it is just plain unnecessary here! While it looks like no big deal, it really is! Like cancer, addingnullto your types can spread easily to other places in your code base. A method that in the past was properly typed with optional parameters (param?: SomeType) will soon be widened to acceptnullas well (param?: SomeType | null). This is, because in a lot of projects, developers just need to get work done, so it's understandable why they're saying "it's easier than fixing thenulltype in my interface right now" and "I'm in a hurry and need to call that method now!".Where
nullcan't be avoidedYou can't always avoid having
nullvalues. This is, because JSON doesn't know the typeundefined, it only knowsnull. However, in my eyes, this is not an excuse to carry thenulltype around all over the code base. I'm not saying to not acceptnullvalues coming in from JSON. All I'm saying is to stop usingnullactively.How does a code base not using
nullat all look like?When following a few coding guidelines,
nullcan always be implicitly treated asundefinedand thus there's no need to add it to any types / interfaces at all.Here are the guidelines that make it possible:
if (value === undefined) { ... }.if (value) { ... }isNilif (!value && value !== 0) { ... })nullDescribe the solution you'd like to see in Angular
null(ideally only as part ofanytype) and handle it properlynullvaluesnullvalues should returnundefinedinstead ofnullConsequences for Angular
I know that this is a huge change and a breaking one as well. A rather long deprecation period would therefore be needed for user adoption.
Describe alternatives you've considered
As it is a matter of (admittedly very debatable) taste, there will surely exist a multitude of alternatives and other opinions. I would like to not open up discussion here on how
nullis useful to somebody in some cases. Such a discussion can be found here ... Instead, please just up/downvote this feature request if you agree/disagree. Thanks a lot!Best Regards, Nic
The text was updated successfully, but these errors were encountered: