December 20, 2025

Nothing is Something

aka please go watch Metz's talk, I'm begging you
edit

I really need more people to watch “Nothing is Something” by Sandi Metz so I don’t get weird looks when I apply its lessons to my code.

I was dealing with a problem like the following today. Imagine you got an object of key/value pairs, where the key is a bit of state and the value transforms that state somehow.

// Just some arbitrary state for our example
type State = {
  count: number
  createdAt: Date
  isActive: boolean
  name: string
}

type Transform = <T>(x: T) => T

const STATE_TRANSFORMS: Partial<Record<keyof State, Transform>> = {
  count: x => x * 2,
  name: x => x.toUpperCase(),
}

The transforms themselves aren’t terribly important, but notice that I don’t have a transformation for every key in the State type.

Now, if you were to make a function to run those transforms, you might be tempted to do:

function transformStates(state: State) {
  const nextState: State = {}

  for (const key of state) {
    const transform = STATE_TRANSFORMS[key]

    // This handles the condition at the last possible moment
    // and it results in two separate ways of managing the state
    if (transform) {
      nextState[key] = transform(state[key])
    } else {
      nextState[key] = state[key]
    }
  }

  return nextState
}

But I prefer to do this instead:

const identity = x => x

function transformStates(state) {
  const nextState = {}

  for (const key of state) {
    // Condition is handled a step earlier and we've narrowed
    // the type of `transform` from `Transform | undefined`
    // to just `Transform`, simplifying the next step
    const transform = STATE_TRANSFORMS[key] ?? identity

    nextState[key] = transform(state[key])
  }

  return nextState
}

Because, as the title of the talk suggests, doing nothing is doing something.

You might argue that I’m making unnecessary function calls here, but I think it’s a worthwhile trade-off for simpler code.

We can use this pattern of identifying the “nothing”, aka the default behavior, and providing the functionality for it as a way to simplify our code, primarily by reducing excessive conditionals which tends to be the source of complexity.

Please watch the talk. You’ll be a better programmer for it.


Liked the post?
Give the author a dopamine boost with a few "beard strokes". Click the beard up to 50 times to show your appreciation.
Want to read more?
Newer Post: AsyncData
Kyle Shevlin's face, which is mostly a beard with eyes

Kyle Shevlin is the founder & lead software engineer of Agathist, a software development firm with a mission to build good software with good people.

Logo for Just Enough Functional Programming
Just Enough Functional Programming
Check out my courses!
If you enjoy my posts, you might enjoy my courses, too. Click the button to view the course or go to Courses for more information.
Sign up for my newsletter
Let's chat some more about TypeScript, React, and frontend web development. Unsubscribe at any time.