The empty object type - {} - doesn't behave how you expect in TypeScript.
Instead of representing an empty object, it represents any value except null and undefined.
This is because TypeScript's type system is structural, not nominal. Everything except null and undefined is an object, so everything can be assigned to an empty object.
If you want to represent an empty object, use Record<string, never> instead.
The empty object type in TypeScript doesn't really behave as you expect. It doesn't represent "any object". Instead, it represents any value that isn't null or undefined.
Try experimenting with it in the playground below:
Here, we are basically typing example1 as an empty object, yet we can pass a string to it. We can pass a number to it. We can pass a boolean to it and any object to it.
The only things we can't pass to it are null or undefined:
constexample5: {} = null;
Type 'null' is not assignable to type '{}'.2322
Type 'null' is not assignable to type '{}'.constexample6: {} = undefined;
Type 'undefined' is not assignable to type '{}'.2322
Type 'undefined' is not assignable to type '{}'.
If you're using ESLint, you might even hit an error:
Don't use {} as a type. {} actually means "any non-nullish value".
This article explains exactly why this is good advice.
Type 'string' is not assignable to type 'never'.2322
Type 'string' is not assignable to type 'never'.};constemptyObj3: EmptyObj = "str";
Type 'string' is not assignable to type 'EmptyObj'.2322
Type 'string' is not assignable to type 'EmptyObj'.constemptyObj4: EmptyObj = 123;
Type 'number' is not assignable to type 'EmptyObj'.2322
Type 'number' is not assignable to type 'EmptyObj'.
What this does is it means that you can pass an empty object. It's going to stop you from passing anything with a property on it. And it's also going to stop you from passing primitives, or null or undefined.
The only time this might be useful is if you want a really wide constraint on a function. Let's say you want to make sure that the thing that you're passing that function isn't null or undefined:
Inside myGenericFunc, we want to make sure that we can't pass null or undefined into the generic function. If we hover over myGenericFunc here, you can see that it's capturing str and returning it in the results here.
But it fails when we try to pass in null or undefined.
constresult4 = myGenericFunc(null);
Argument of type 'null' is not assignable to parameter of type '{}'.2345
Argument of type 'null' is not assignable to parameter of type '{}'.constresult5 = myGenericFunc(undefined);
Argument of type 'undefined' is not assignable to parameter of type '{}'.2345
Argument of type 'undefined' is not assignable to parameter of type '{}'.
So, you probably shouldn't be using the {} type really anywhere. And you'll have likely come to this article because you found a linting rule that's preventing you from using it. That is why it doesn't represent what you think, but it's occasionally useful for constraining generics.
Got any more questions? Found any more use cases? Let me know: