Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty interface allow any object?

Tags:

typescript

Why empty interface doesn't require object to be empty?

interface A {};
const a: A = {a: 1};
console.log(a);

is valid code and will output { a: 1 }.

I would assume that adding optional property should work fine, but

interface A {};
interface B extends A {
    b?: any;
}
const a: B = {a: 1};
console.log(a);

ends with error Type '{ a: number; }' is not assignable to type 'B'.

  • If interface define what properties object must have, B case should work fine, all required properties are present.
  • If interface define what properties object can have, A case should result in error, a is not defined in interface.

Non empty interface defines both what object can and must have. Empty interface behaves like any.

Is there explanation why empty interface behaves like this? Is this intentional or just a bug?

like image 748
mleko Avatar asked Mar 01 '17 17:03

mleko


1 Answers

This behavior is intentional.

The excess property check is not performed when the target is an empty object type since it is rarely the intent to only allow empty objects.


Actually, you can assign {a: 1} to B, the other answers here are mostly wrong.

You have stumbled upon another slightly confusing quirk in TypeScript, namely that you can not directly assign an object literal to a type where the object literal contains other properties than the one specified in the type.

However, you can assign any existing instance of an object to a type, as long as it fulfill the type.

For example:

interface Animal {
    LegCount: number;
}

let dog: Animal = { LegCount: 4, Fur: "Brown" }; // Nope

var myCat = { LegCount: 4, Fur: "Black" };
let theCat: Animal = myCat; // OK

This constraint is simply ignored whey you have a type that is empty.

Read more here and here.

A later answer from the Typescript team is available on GitHub.

like image 134
Alex Avatar answered Sep 28 '22 12:09

Alex