All values match empty interfaces
While an empty interface ({}
) intuitively represents an empty object ({}
), the function doSomething
below considers any data type (strings, numbers, booleans) as belonging to the empty interface Thing
.
This is the expected behavior, because the type {}
actually means any non-null
/undefined
value with zero or more properties. Primitive values like strings and numbers do have properties (e.g. length
for strings). The only data types that do not have properties are null
and undefined
.
The type that refers to objects is object
. The precise definition of object
is any value which has Object
in its prototype chain, which excludes strings and numbers but may include several other built-in data types like arrays.
Here is the correct way to construct a type that represents an "empty object".
A note on Symbols
It is not possible to detect certain known symbols like Symbol.toPrimitive
with TypeScript, even though they are guaranteed to exist on the underlying value.
A note on property checks
Notice that excess property checks do not apply to {}
.
- TODO: example