1

With "noImplicitAny": true in tsconfig.json:

const a = {}
console.log(a['b']) //  Property b does not exist on type {}.
console.log(a.b) //  Property b does not exist on type {}.

With "noImplicitAny": false in tsconfig.json:

const a = {}
console.log(a['b']) //  no error
console.log(a.b) //  Property b does not exist on type {}.

Why there's no error for the second console.log(a['b']) while the second console.log(a.b) throws?

Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
  • Well for me it' only a matter of how strong you want the type checks to be. It probably doesn't answer your question, but if you really don't know the type of your object, you can type it explicitly as _any_: the 2 errors will disappear and you will have to make sure in the rest of your code to check that your properties exist (i.e. are not undefined) before using them. – clementlize Jun 29 '23 at 09:06

1 Answers1

0

See microsoft/TypeScript#43431 for an authoritative answer to this question.

Using bracket notation is intentionally allowed so that you can perform otherwise prohibited indexes. So if foo.bar is disallowed, you can work around it with foo["bar"]. But when you do that and the property isn't known to exist, the resulting property type is implicitly any. As such, you get an error if and only if --noImplicitAny is enabled.

You'll notice that the error for a["b"] is different from the error for a.b when --noImplicitAny is enabled. They both mention that b doesn't exist on type {}, but for a["b"] you also get: Element implicitly has an 'any' type because expression of type '"b"' can't be used to index type '{}'.

jcalz
  • 264,269
  • 27
  • 359
  • 360