All of this compiles without error:
interface Empty { }
interface MaybeEmpty { a?: number; }
var one: Object = 20;
var two: Empty = 21;
var three: {} = 22;
var
Update for TS2.4+, there is now weak type detection which will prevent assigning to all-optional-property types like MaybeEmpty
if there are no overlapping properties, so var four: MaybeEmpty = 23
is now not permitted.
Update for TS2.2+, there is now an object type which specifically excludes primitives. Object-like types using curly braces like {}
or { a?: number }
are still compatible with primitives, as mentioned below.
Original answer:
No.
The root problem is that JavaScript often treats primitive values as if they were their Object-typed equivalents (String
/Number
/etc) when used in a context where an object is required (e.g. property access).
TypeScript models this using the "apparent type" whereby objects of a primitive type appear to have the members of their corresponding Object types. This is because, intuitively, code like this should compile without error:
function fn(x: { toString(): string }) { /* ... */ }
fn(32); // Should be OK because (32).toString() is OK
fn('foo'); // Should be OK because ('foo').toString() is OK
It's a small step to this code:
function fn(x: { toString(): string; other?: whatever; }) { /* ... */ }
fn(32); // Should be OK
fn('foo'); // Should be OK
And another small step to this code:
function fn(x: { other?: whatever; }) { /* ... */ }
fn(32); // OK, I guess?
fn('foo'); // OK, I guess?
There's an issue on GitHub tracking the general problem that an interface with all optional properties is effectively never the source of an error when assigning to it. It's a very hard thing to spec.