- "primitive":
boolean
,number
,string
,symbol
,null
,undefined
- "object" aka "non-primitive": any "custom object" (e.g.
{ foo: 1 }
) or function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types
(In JS, people mistakingly think of primitives as "object"s, but in strict JS terminology, they're not.)
An "object" aka "non-primitive" (as per JS terminology above).
const myObject: object = primitive // error
const myObject: object = customObjectOrFunction // no error
The class instance behind any "object".
primitive instanceof Object // false
customObjectOrFunction instanceof Object // true
// At first glance, we would expect this to error, so that TS' behaviour matches
// JS's runtime behaviour. However, TS only cares about structures, so this does
// not error.
const myObject: Object = primitive;
const myObject: Object = customObjectOrFunction;
// Note: `Object` value === `ObjectConstructor` type
An object
but specifically one without any properties (TODO: correct?).
const myObject: {} = {}; // no error
// At first glance, we would expect this to error, but it doesn't. TODO: why?
const myObject: {} = { foo: 1 };
The reason
Object
exists is so that TypeScript a place to understand the properties exist on all JavaScript objects which have the global valueObject.prototype
in their__proto__
chain. In other words, for values which areinstanceof Object
, those values should appear to have methods likehasOwnProperty
(even though the types of those values don't include those properties!). Probably in retrospect this type should have been better-hidden.Not correct, on two counts.
{}
is the empty type and is assignable from any non-null/non-undefined type. Remember structural typing here: Reducing the number of properties in a type (should) never decrease the number of types which are assignable to it (n.b. excess property checking is not a factor in assignability; it is a separate check).Note some problematic symmetry here:
string
should be assignable to{ length: number }
, and for any type{ r0; r1; r2...}
, a value assignable that type should also be assignable to{ r1; r2...}
. So ifstring
is assignable to{ length: number }
(which it absolutely should be), thenstring
must also be assignable to{ }
, even though it's not an object.