Typescript doesn't catch `state` type errors outside of constructor?

483 views Asked by At

enter image description here

In the image above, I have set default state values incorrectly (this_is_not_ok is not part of the State interface). Typescript does not seem to mind, though. One way to fix the issue was to explicitly add a type annotation.

I could also fix the issue by using a constructor():

constructor(){ super(); this.state = {spelling_error: "wrong"}; }

Why did type inference not work in the first example?

1

There are 1 answers

2
Ryan Cavanaugh On BEST ANSWER

I have set default state values incorrectly

You haven't set the values incorrectly. You've simply written a class which has more state than the base class, which is not an error per se. When you write a derived class, you can have more stuff than your base class.

When you write a class property initializer without a type annotation, TypeScript infers the type of the property based on the initializer:

interface Bar {
  stuff: { x: number }
}

class Foo implements Bar {
  stuff = {
    x: 10, y: 3
  }
}
const f = new Foo();
console.log(f.stuff.y); // OK: f.stuff is of type { x: number; y: number; }

The implements check simply means "Make sure this class can be used as the interface type". The same thing happens for a derived class: because you have at least the stuff mandated by the contract of the base class, then everything is fine.

If you have an explicit type annotation, or do the initialization in the constructor, then the general rules for assigning an object literal apply - no extra properties allowed.


For what it's worth, this behavior might change in a future release of TypeScript. See https://github.com/Microsoft/TypeScript/issues/10570