Reputation: 13
type Valid = 'A' | 'B'
type SomeType = { [index in Valid]: string }
const x: SomeType = {
A: 'foo',
B: 'foo',
};
let idx = 'A';
const v1 = x[idx];
Running tsc on the above snippet gives error Element implicitly has an 'any' type because type 'SomeType' has no index signature
.
Has SomeType
not been provided with a signature here:
type SomeType = { [index in Valid]: string }
?
Upvotes: 1
Views: 150
Reputation: 249716
The error occurs because typescript will only allow index access (under the noImplictAny
option) only if it can prove the access is valid. This means that x["A"]
is valid, but x
of a random variable of type string
is not valid.
Typescript will also let you perform the access if the variable not typed asstring
but as a union of string literal types that can be key of the index target. So this will work as well:
let idx: "A" | "B" = 'A';
const v1 = x[idx];
Or you can use the keyof
type operator to get a union of all possible of a type:
let idx: keyof SomeType = 'A';
const v1 = x[idx];
Or you can use const
instead of let to force the compiler to infer a string literal type for idx
if it does not change:
const idx = 'A'; // idx is of type 'A'
const v1 = x[idx];
Or you can use a const
assertion to tell the compiler not to widen the literal type even for a let
declaration (although `idx will only have one possible value)
let idx = 'A' as const; // idx is of type 'A'
const v1 = x[idx];
Upvotes: 1