Skip to content

Instantly share code, notes, and snippets.

@jossmac
Last active May 21, 2026 01:18
Show Gist options
  • Select an option

  • Save jossmac/aae65585c6c01a7141a28a7825ff17be to your computer and use it in GitHub Desktop.

Select an option

Save jossmac/aae65585c6c01a7141a28a7825ff17be to your computer and use it in GitHub Desktop.
It's JavaScript that's complicated, not TypeScript

It's JavaScript that's complicated, not TypeScript

When I first started writing TypeScript, it felt strange and bureaucratic, like I was being asked to constantly justify things that were already obvious.

Then, after enough time, you realise TypeScript isn’t being pedantic. It’s compensating for the fact that JavaScript itself is wildly permissive.

Everything is an object, somehow

JavaScript’s type system has the energy of a witness being cross-examined.

Is this thing an object? "Yup"

An array? "Maybe"

Is it something, at least? "Probably, but it could be null"

Wait, is it a date? "Ah, you got me! Yeah, it's a date, lol…"

typeof {}          // "object"
typeof []          // "object"
typeof null        // "object"
typeof new Date()  // "object"

Which leads to half of modern frontend engineering becoming:

if (
  value &&
  typeof value === "object" &&
  !Array.isArray(value) &&
  !(value instanceof Date)
) {
  // finally, maybe (not), a plain object
}

Trust, but verify

JavaScript:

Everything is an object until proven otherwise.

TypeScript:

I would like to see the proof.

Where does it end?

There’s a comical number of things that satisfy the "object" type, including:

  • Arrays
  • null
  • Date
  • Map
  • Set
  • RegExp
  • Errors
  • Typed arrays (Uint8Array, etc.)
  • Promise
  • Boxed primitives (new String("x"))
  • Class instances
  • DOM nodes
  • URL
  • ArrayBuffer
  • WeakMap / WeakSet
  • Literally objects with custom prototypes
  • Objects created with Object.create(null) that aren’t even instances of Object

So, if you don't want a type guard that starts to look like:

value &&
typeof value === "object" &&
!Array.isArray(value) &&
!(value instanceof Date) &&
!(value instanceof Map) &&
!(value instanceof Set)

Just use this, which contains the accumulated trauma of an entire ecosystem:

isPlainObject(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment