Reputation: 13327
I have this example code:
const example: { [key: string]: string } = { a: 'abc' }
const b = example['b']
At runtime, b
would obviously be equal undefined
, but at compile type, Typescript infers b
type to be just string
and not string|undefined
. This seems like an error to me.
Why doesn't it infer it as string|undefined
, and how can I force it to do so?
Upvotes: 2
Views: 278
Reputation: 35560
You broaden the type by casting it to {[key: string]: string}
, so from a type perspective, 'b'
is as valid a key as 'a'
. Omit the type and let typescript infer a narrower type, and an error will be thrown:
const example = { a: 'abc' };
// error: property 'b' does not exist
const b = example['b'];
There's a discussion about adding | undefined
to index lookups on GitHub issue #9235, and it was actually resolved with a noUncheckedIndexedAccess
flag added in typescript 4.1. If it's set, then b
will be string | undefined
, even in your example.
Upvotes: 3
Reputation: 23575
It's not an error. Considering typing only : 'b'
could be a valid key.
The type { [key: string]: string }
specifycally tells Typescript that example
can contains any key name.
Typescript is not analyzing your variable. It only compare type and see if they match.
In the following example typescript show you an error. Because you list the keys that can exists or not.
type keys = 'a' | 'foo';
const example: { [key in keys]?: string } = { a: 'abc' }
const b = example['b']
Upvotes: 3
Reputation: 171
You are casting example to be of { [key: string]: string }
type. In other words, you are telling typescript it is always a string. There is no way of typescript analysing if it is really on there or not as its a statically typed language.
Upvotes: 0