- "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 errorThe 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` typeAn 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
Objectexists is so that TypeScript a place to understand the properties exist on all JavaScript objects which have the global valueObject.prototypein 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:
stringshould 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 ifstringis assignable to{ length: number }(which it absolutely should be), thenstringmust also be assignable to{ }, even though it's not an object.