Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically access object property in TypeScript

I've been going through and trying to convert existing projects (from Node.js) to TypeScript.

For context, I'm using the http-status package (https://www.npmjs.com/package/http-status)

I'm trying to pass variables through into their default export, but it's getting an error:

import status = require("http-status");

status.OK; // this works
status["OK"] // this also works

let str = "OK";
status[str]; // error

Error:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'HttpStatus'.
No index signature with a parameter of type 'string' was found on type 'HttpStatus'.


How would I convert this usage to TypeScript?

like image 892
lukesrw Avatar asked Jun 17 '20 21:06

lukesrw


People also ask

How do you use a variable to access the object property?

Answer: Use the Square Bracket ( [] ) Notation There are two ways to access or get the value of a property from an object — the dot ( . ) notation, like obj. foo , and the square bracket ( [] ) notation, like obj[foo] .

How do I create a dynamic object key?

To create an object with dynamic keys in JavaScript, you can use ES6's computed property names feature. The computed property names feature allows us to assign an expression as the property name to an object within object literal notation.

How do you check if an object has a property in TypeScript?

To check if a property exists in an object in TypeScript: Mark the specific property as optional in the object's type. Use a type guard to check if the property exists in the object. If accessing the property in the object does not return a value of undefined , it exists in the object.


3 Answers

"OK" is a string, and str is implicitly taking the type string in your code.

When you try to access an object's property, you need to use a type keyof. TypeScript then knows you are not assigning a random string; you are assigning strings compatible with the properties (keys) for the object.

Also, since status is a variable, not a type, you need to extract its type with typeof.

Try:

let str = "OK" as keyof typeof status;
status[str]; // 200

or more cleanly:

type StatusKey = keyof typeof status;
let str: StatusKey = "OK";
status[str]; // 200

// and to answer the question about reversal
status[status.OK as StatusKey]; // OK

See: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types

like image 166
Guillaume F. Avatar answered Oct 17 '22 17:10

Guillaume F.


Actually there's a simpler fix, you just have to just use const assertion.

Here's the fix:

const str = "OK" as const; // <-- add "as const", now `str` has type of "OK" instead of `string`
status[str]; // No more error!

Playground link.

like image 23
Wong Jia Hau Avatar answered Oct 17 '22 17:10

Wong Jia Hau


I had to access second level dynamic key from an object.

const myObj = {
  "address": {
    "street": "Main ave",
    "city": "NYC"
  }
}

secondLevelDynamic(field: string) {

  let dynamicKey = field as keyof myObj;

  let myProp = this.myObj['address'];
  let myDynamicPropValue = myProp[dynamciKey]
}
like image 24
Amit .NET Avatar answered Oct 17 '22 15:10

Amit .NET