jngk
jngk

Reputation: 13

Why does tsc report that SomeType has no index signature?

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

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

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

Related Questions