26
loading...
This website collects cookies to deliver better user experience
null
, nil
, etc.) debate about avoiding it, JavaScript is the only popular one that has two, you read that right, two nullish types. One of the most common recommendations is to stick to using only one, and my recommendation is to only use undefined
and avoid null
. In this article, we will go over the reasons you might also want to avoid null
in JavaScript and TypeScript.I call it my billion-dollar mistake (...) My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
undefined
over null
.undefined
all the time, so let's use the one the language uses:let something; // This is undefined!
const otherThing = {
foo: "hi",
};
otherThing.bar; // This is also undefined
const aFunction = anArgument => {
// anArgument here is undefined if no value is passed
};
null
on all those scenarios, we need to explicitly set the values to null
, which will look like this:let something = null;
const otherThing = {
foo: "hi",
bar: null,
};
const aFunction = (anArgument = null) => {};
undefined
to it:const anObject = {
...otherObject,
propertyToNullify: undefined,
};
typeof null
, that bug doesn't apply to undefined
which works as expected:typeof null; // "object" 🤷🏻
typeof undefined; // "undefined" 🎉
undefined
instead of null
. Here's a response example using null
:{
"foo": "foo",
"bar": null
}
undefined
:{
"foo": "foo"
}
Array
is a special case, because when we create a new array of a given size, the items inside said array are actually empty
, not undefined
. This empty
means that if you check for their value, it will give you undefined
, but they aren't taking any space in memory (performance reasons), so if you try to loop over it, it will give you nothing:const array = new Array(3); // [empty, empty, empty]
array[0] === undefined; // true
array.map(console.log); // nothing logs 🤦🏻
null
, folks that use it a lot (generally coming from other languages that have null
as the only nullish value) get pretty mad about such claims. The most common response I get is:null
is for intentional missing values, and undefined
should be used when the values were never set in the first place.
null
is to do stuff like this:const people = [
{
firstName: "Luke",
middleName: null,
lastName: "Shiru",
},
{
firstName: "Barack",
middleName: "Hussein",
lastName: "Obama",
},
];
middleName
when the user doesn't have one:const people = [
{
firstName: "Luke",
lastName: "Shiru",
},
// ...
];
middleName
to an empty string if the user intentionally left that blank, if you really need to know that for some reason:const people = [
{
firstName: "Luke",
middleName: "",
lastName: "Shiru",
},
// ...
];
type Person = {
firstName: string;
middleName?: string;
lastName: string;
};
null
value there, or bits with a JSON coming from the back-end, when we can just omit what is not there?But the API is responding with null
(maybe written in Java), so I have to use null
all over my app as well.
null
all over your codebase, update your surface of contact with the API so null
s are removed, and if you have any contact with the folks making the API, voice your concern of making API responses smaller by getting rid of null
values. You should try to avoid ending up over-engineering/over-complicating your app just to deal with null
when you can just avoid it altogether.But in React I use null
when I want a component to not render anything
undefined
as well.You have to type 5 more characters when you write undefined
explicitly in your code.
null
.Maybe
, which is a type that means "we might get a certain type or nothing". We can do a simple implementation of that in TypeScript like this:type Maybe<Type> = Type | undefined;
undefined
. We can just use ?
as well when it's a property or argument:const aFunction = (optionalArgument?: Type) => // ...
type AnObject = {
optionalProperty?: Type;
};
??
) and optional chaining (?.
), so...// We don't need to do something nasty like this:
const greet = name => `Hello, ${name !== null ? name : "Guest"}`;
// We can do this:
const greet = name => `Hello, ${name ?? "Guest"}`;
// Or better yet, because we are using undefined, we can actually...
const greet = (name = "Guest") => `Hello, ${name}`;
null
is not a good nullish value, you can avoid it from now on using this great ESLint plugin, and just add this to your linting rules:{
"plugins": ["no-null"],
"rules": {
"no-null/no-null": "error"
}
}
null
:null
in favor of undefined
in Angular.null
in JavaScript is "anything written with null
can be written with undefined
instead", but your millage might vary, so as usual I close this article with a few open questions: Do you NEED to use null
? Don't you have a way of resolving that issue without it?Disclaimer
This series is called "You don't need ...", emphasis on need, meaning that you would be fine without the thing that the post covers. This series explores alternatives, it doesn't impose them, so consider that before glancing over the post and ranting on the comment section. Keep it respectful.