How to Type Empty Objects in TypeScript
A common mistake I see when people are writing their types for empty objects is this:
// ❌ Don't do this: type EmptyObject = {};
Why?
The assignment of {}
just means any non-nullish value.
This means we can assign everything except null
to our type.
As an example:
type EmptyObject = {}; // ✅ Passes the Type check: const test1: EmptyObject = "This is a test"; // ✅ Passes the Type check: const test2: EmptyObject = {}; // ✅ Passes the Type check: const test3: EmptyObject = { test: "Yes, I work too...", }; // ❌ Fails the Type check: Type 'null' is not assignable to type 'EmptyObject' const test4: EmptyObject = null;
How to enforce an empty object?
To declare an object as an object with no properties, we have to be more explicit:
type EmptyObject = Record<PropertyKey, never>;
Now if we tried to assign a value we will start seeing type errors.
type EmptyObject = Record<PropertyKey, never>; // ❌ Fails the Type check: Type 'string' is not assignable to type 'EmptyObject'. const test1: EmptyObject = "This is a test"; // ✅ Passes the Type check const test2: EmptyObject = {}; // ❌ Fails the Type check: Type 'string' is not assignable to type 'never'. const test3: EmptyObject = { test: "Yes, I work too...", }; // ❌ Fails the Type check: Type 'null' is not assignable to type 'EmptyObject' const test4: EmptyObject = null;
How does this work?
The Record
utility lets us define the accepted keys and values.
Its structure is:
Record<Keys, Type>
The PropertyKey
is an alias that says the key can be a string
, a symbol
, or a number
(or a normal property key).
Then the never
says the value will never occur, meaning if we try to assign a value to a key, we will get a type error.
Follow me on Twitter or connect on LinkedIn.
🚨 Want to make friends and learn from peers? You can join our free web developer community here. 🎉