How to access a property of an object using the bracket notation in TypeScript strict mode

Issue

The following TypeScript sample code shows an error Element implicitly has an 'any' type because type '{one: number; two: number;}' has no index signature in the line const one = obj[prop]; in strict mode.

The compiler allows the line const two = obj[propName];, so I cannot understand why the error is shown or how to generally speaking access a property of an object using the bracket notation.

const obj = { one: 1, two: 2 };

const props = { one: 'one', two: 'two' };

// it is not possible add or change any properties in the props object 
props.zero = 'zero';
props.one = 1;

// prop has the type string
const prop = props.one;

// using the bracket notation fails with the following error message:
// Element implicitly has an 'any' type because type '{one: number; two: number;}' has no index signature.
// const prop: string
const one = obj[prop];

// this works because propName is of type 'two'
const propName = 'two';
const two = obj[propName];

Solution

Element implicitly has an ‘any’ type because type ‘{one: number; two: number;}’ has no index signature

Your object has no index signature, it has two named properties.

The compiler allows the line const two = obj[‘two’];

It allows the names of your properties, that’s why obj[‘two’] and obj[‘one’] will work.

and the const prop is a string, so I cannot understand why the error is shown

Because a string can have much more values that just ‘one’ or ‘two’ and so the compiler cannot ensure, your object[myString] call will work. It’s only valid for two defined string values.

how to generally speaking access a property of an object using the bracket notation.

This would work:

 const prop: 'one' | 'two' = 'one';
 const test = obj[prop]

You say: prop has value ‘one’ or ‘two’ and so the compiler knows your obj[prop] will always be valid.

or

 class Example {
   one: string;
   two: string;
 }
 const prop: keyof Example = 'one';
 const test = obj[prop];

Here keyof(ClassName) tells the compiler, that your prop var will have an existing property name of Example.

The above examples assume, that you have an object where only the properties named ‘one’ and ‘two’ are valid. If you want to use your object in a “dictionary style”, tell typescript about that and add an index signature:

 const obj: {[key:string]: string;} = { one: 'one' };
 const text = obj[myString];

Now obj allows every string values as key.

Answered By – Christoph Lütjen

Answer Checked By – Dawn Plyler (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.