I posted the image above on Twitter with the caption “Almost vegan”—as a (bad) joke about how something cannot be “almost vegan”. Peter Kofler answered “Almost pregnant”, which made me think of… programming, of course. Types, in particular.
Some food either is vegan, or it is not. Something that is almost vegan is still not vegan. Like the food I cooked: It looks like it might be vegan, but the noodles contain a bit of egg, so it isn’t.
One might argue that the food pictured here is more vegan than e.g. steak and potato skins, with all the cheese and bacon and beef—i.e. that there are different shades of true and false. Let’s ignore that for now—It would take us into the realm of fuzzy logic; A topic that I might explore somewhere around part 97 of this series, if I ever get that far.
In typescript, you would say that the property—whether something is vegan or not—is of type boolean
:
const vegan: boolean = false
The type boolean can only hold a finite set of values. true
and false
, and also null
and undefined
in the default configuration (where null
and undefined
are two different ways of saying “I don’t know”). Or, in Roster notation and as an Euler diagram:
boolean = { true, false, null, undefined }
All the types in TypeScript describe a set of possible values. You can imagine them to be sets like your maths teacher explained them to you back when you talked about set theory.
So, a variable of type boolean
, like vegan
from our first code snippet, can hold any value from this set, but nothing else. Changing the code like below leads to a compiler error:
const vegan: boolean = 0.9 //ERROR
//Type 'number' is not assignable to type 'boolean'.(2322)
We can create a smaller set of possible values by creating a type that can only ever have the value true
type MyTrue = true
const b1: MyTrue = true
const b2: MyTrue = false //ERROR
//Type 'false' is not assignable to type 'true'.(2322)
In the default configuration, null
and undefined
are part of every set.
const b3: MyTrue = undefined
const b4: MyTrue = null
But most of the time, this is not what we want. It is just too permissive and prevents us from catching errors early. Imagine asking “Is this dish vegan?” and the waiter answers “null”. I guess that, whatever was the reason for your question, this is not an answer you can accept.
So, let’s turn on strict
mode in tsconfig.json
and try again…
const b3: MyTrue = undefined //ERROR
//Type 'undefined' is not assignable to type 'true'.(2322)
const b4: MyTrue = null //ERROR
//Type 'null' is not assignable to type 'true'.(2322)
Much Better! boolean
s, and all other data types, now too have null
and undefined
removed from their sets of possible values—null
and undefined
now form their own sets.
And that is enough for today. In the next installment, I want to write about what it means when you want a boolean that could also be null and/or undefined in strict mode.