Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

typescript

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];
like image 422
doberkofler Avatar asked May 02 '19 19:05

doberkofler


People also ask

How do you access the properties of an object in TypeScript?

To dynamically access an object's property: Use keyof typeof obj as the type of the dynamic key, e.g. type ObjectKey = keyof typeof obj; . Use bracket notation to access the object's property, e.g. obj[myVar] .

How do you use bracket notation?

Bracket notation is another way to access a property of an object. To use bracket notation, write the name of the object, followed by brackets [] . Inside the brackets, write the property name as a string. Bracket notation, unlike dot notation, can be used with variables.

How are brackets used for objects in JavaScript?

The alternate syntax for accessing object properties is known as bracket notation. In bracket notation, the object name is followed by a set of square brackets. Inside the square brackets, the property name is specified as a string.


1 Answers

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.

like image 130
Christoph Lütjen Avatar answered Nov 15 '22 03:11

Christoph Lütjen