Using Types to Prevent Null in Lists

Your east/west dashboard shows “us-east-1, us-west-2, and NULL” (1st image). How can types prevent that?


Our types currently:

type RegionsPossibly = Array<any>
regions1 = [ 'us-east-1', 'us-west-2', null ]Code language: JavaScript (javascript)

The regions Array is actually a union of string or null, so:

type RegionsMaybe = Array<string | null>Code language: JavaScript (javascript)

That means you’d have to filter them out at runtime.

Kibosh that nonsense, let’s have an Array of strings only:

type Regions = Array<string>
regions3 = [ 'us-east-1', 'us-moo-cow-moo' ]Code language: JavaScript (javascript)

Oh no, that removed the null’s/undefined’s, but now we have the possibly a region isn’t really a region.

… what _is_ a Region?

Let’s define a region using a Union to narrow it to just 2:

type Region = 'us-east-1' | 'us-west-2'
type RegionsForRealDoh = Array<Region>Code language: JavaScript (javascript)

We’re good now, right?

regions4 = [ 'us-east-1', 'us-west-2', 'us-east-1' ]Code language: JavaScript (javascript)

Oh no… Array’s allow duplicates!

Tuple’s are fixed length Array’s and fixed position. Let’s define all possible combo’s:

type RegionsAndOnlyOne =
  | ['us-east-1', 'us-west-2']
  | ['us-west-2', 'us-east-1']Code language: JavaScript (javascript)

Nice! This compiles:

regions5 = ['us-east-1', 'us-west-2']Code language: JavaScript (javascript)

But if you added dupes, it wouldn’t.

“Hey, can you add ‘eu-west-2’?”

Dude… tuples are cool, but also exponential based on their amount. That’s a type with >9 possible combo’s, I’m not writing all that! What if there were a way to create a type from a Union that handled that in case you need to add a new one later?

type Permutations<T, U = T> =
  [T] extends [never]
    ? []
    : T extends T
      ? [T, ...Permutations<Exclude<U, T>>]
      : never

Think of Permutations like a function, but for types.

We can use that to create a more flexible way to creating fixed tuples for drawing lists in our UI code without having to manually type all permutations. As the list grows, the type will become quite unreadable too.

Let’s add our new region to our Union:

type RegionNew = 'us-east-1' | 'us-west-2' | 'eu-west-2'Code language: JavaScript (javascript)

Then create a type using our type function vs. manually typing all the possible tuples:

type RegionsWithEU = Permutations<RegionNew>

regions6:RegionsWithEU = [
  'us-east-1',
  'us-west-2',
  'eu-west-2'
]Code language: JavaScript (javascript)

That allows any order with no duplicates. It’s safe to use in your naive React/Angular/Vue code to iterate through a list and draw it, no Cypress/Playwright or Unit Tests needed to validate.

Much more preferable, and flexible compared to the 2nd attached image 😅.

And with that, your NULL/undefined issue in your UI is crushed, no unit tests or acceptance tests needed. (That said, you should still write tests).

Happy (and safe) array dot map ‘ing!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *