Utilize key-value pairs to reference variables when importing as a namespace

Is it feasible to utilize a string for performing a lookup on an imported namespace, or am I approaching this the wrong way?

Consider a file named my_file.ts with contents similar to:

export const MyThing: CustomType = {
    propertyOne: "name",
    propertyTwo: 2
}
export const AnotherThing: CustomType = {
    propertyOne: "Another",
    propertyTwo: 3
}

Now, if there is another file that imports these and needs to access them dynamically based on a string:

import * as allthings from "dir/folder/my_file"


function doStuff() {
   let currentThing = allthings['MyThing']; // works
   let name = 'MyThing';
   let currentThing2 = allthings[name]; // doesn't work

}

The error encountered is:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof import("dir/folder/my_file")'. No index signature with a parameter of type 'string' was found on type 'typeof import("dir/folder/my_file")'

Why does a literal string work but not a variable of type string in this scenario?

Answer №1

The direct string assignment may not be secure as the value can be altered at any time for the variable let name.

A safer approach is to use a const. You can also cast it explicitly:

let name = 'MyThing' as const;

However, it is recommended to declare a const variable directly which achieves the same outcome. Using let is unnecessary if the intention is not to change the value.

const name = 'MyThing';

Check out this TS playground demo

If the key is unknown in advance and all objects within my_file are of the same type (CustomType), you can safely utilize keyof typeof allthings as the type

export const allthings = {
  MyThing: {
    propertyOne: "name",
    propertyTwo: 2
  },
  AnotherThing: {
    propertyOne: "Another",
    propertyTwo: 3
  }
};

type CustomType = typeof allthings[keyof typeof allthings];

function getValue(key: keyof typeof allthings): CustomType {
    return allthings[key]; 
}

Refer to this TS example

For enum-like structures, consider using

satisfies Record<string, MyType>
to ensure they share the same type

interface CustomType {
  propertyOne: string,
  propertyTwo: number
}

const allthings = {
  MyThing: {
    propertyOne: "name",
    propertyTwo: 2
  },
  AnotherThing: {
    propertyOne: "Another",
    propertyTwo: 3
  }
} satisfies Record<string, CustomType>;

function getValueFromAllThings(key: keyof typeof allthings): CustomType {
    return allthings[key]; 
}

Answer №2

I came across a similar question on this forum: Dealing with 'any' type error when using a string as an index

After some trial and error, I managed to solve the issue by implementing the following:

import * as allitems from "dir/folder/my_file"


function handleItems() {
   let currentItem = allitems['MyItem']; // This now works
   let itemName = 'MyItem';
   let currentItem2 = allitems[itemName as keyof typeof allitems]; // Also works

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to showcase a list from intricate JSON data using Angular

I recently came across this pre-existing JSON data that I am unable to change: {"tags": [ { "title": "news", "options": [ { "title": "important", }, { "title": "less important", ...

Leveraging the power of map in an Angular typescript file

I've been attempting to populate a Map in Angular by setting values dynamically. When certain buttons are clicked, the onClick function is invoked. typeArray: Map<number,string>; Rent(movieId: number){ this.typeArray.set(movieId,"Rental ...

Is there a way to seamlessly update button values in VueJs from an api request without needing to reload the page or manually clicking something? Or perhaps there is an alternative method to achieve this?

I attempted to solve the issue by implementing while(true) within the created method so that it constantly updates by sending frequent requests to Flask. Is there a different approach to updating my value? Vue: let app = Vue.createApp({ data ...

Using Fetch API in NextJS requires pressing the Enter key twice for it to work properly

The functionality of this component should display JSON data in the console log after entering input into the search bar and hitting the enter key. However, there is a lag where the data doesn't show until the enter key is pressed a second time. Addit ...

Issue encountered while attempting to run executeJavascript()

Hello, I’m looking to insert the output of a Python function that I have stored in the variable data. However, when I attempt to insert the value of this variable using the command document.getElementById("h1-fs-s5").innerHTML, it doesn’t work as expec ...

ESLint flagging "Unexpected tab character" error with "tab" indentation rule enabled

Currently, my ESLint setup includes the Airbnb plugin (eslint-config-airbnb) along with the Babel parser. I recently decided to enforce the rule of using Tab characters for indentation instead of spaces. This is how my .eslintrc file looks like: { "p ...

Struggling with adding headers in React application

When I try to include an h1 heading, either the heading doesn't show up if I comment out the buttons, or if I comment out the heading, then the buttons don't display. But when both are included, nothing is displayed. Any suggestions on how to fix ...

Tips for effectively using the parseInt function to access and verify a span element from inside a chrome extension

Trying to utilize parseInt to ascertain if a span element is greater than or equal to 1 within my Google Chrome Extension. Attempting to monitor this "0" for changes and trigger a specific URL upon change - Refer to the Image View of the "inspect" option ...

Reordering sections in a dynamic manner

I'm working on a single-page website with four sections arranged like this: <section id=“4”> <section id=“3”> <section id=“2”> <section id=“1”> Now, I want to change the order of these sections when scrolling ...

Starting a Vue.js app with preloaded data

I have a single file component named Foo: <template> <div> This is the main app. X is {{ x }}, y is {{ y }} </div> </template> <script> export default { data() { return { x: 'hello x' }; }, } </script> ...

Retrieve information and auto-fill text boxes based on the selected dropdown menu option

UPDATED QUESTION STATUS I'm currently working with Laravel 5.7 and VueJs 2.5.*. However, I am facing a challenge where I need to automatically populate form textboxes with data from the database when a dropdown option is selected. Despite my efforts ...

Using AngularJS to dynamically load content into Owl Carousel 2

I'm having trouble loading the owl carousel in angularjs dynamic content. Here is the modified html code I am using: <div id="Galeria" owlcarousel class="youplay-carousel gallery-popup"> <a class="angled-img" href="http://www.youtube. ...

I am having trouble comprehending this JavaScript code, could someone provide me with assistance?

Currently delving into the world of JavaScript functions and stumbled upon this code snippet with the following output: Output: "buy 3 bottles of milk" "Hello master, here is your 0 change" function getMilk(money, costPerBottle) { ...

Tips for creating a condensed header

As a newcomer to HTML, I am facing challenges in creating a simple header similar to the one displayed on this website or the example in the image below. Below is the snippet of HTML that I have attempted: <header class="header"> <div ...

Update Button Visibility Based on State Change in ReactJS

Currently, I'm utilizing a Material UI button within my React application. Despite changing the state, the button remains visible on the screen. Here's the relevant code snippet: function MainPage() { const state = useSelector(state => sta ...

Fixing Firebase and React errors in JavaScript functions

Thank you for your understanding. I am currently integrating Firebase into my website. However, when I invoke the signup function in FormUp.js (which is declared in AuthContext.js), it does not reference the function definition. As a result, the function c ...

Scope ng-repeat with Angular's $compile function is not functioning as expected

I am facing an issue with my directive that uses the $compile service to create a template. Despite having the users array defined in my scope, it does not populate the select options using either ng-options or ng-repeat. I am puzzled as to why this is h ...

Implementing jQuery autocomplete on dynamically generated fields post page load

I have successfully implemented jQuery UI Autocomplete to fetch data from a DB and populate a form dropdown. However, I am faced with the challenge of adding more form fields dynamically that also need to have the autocomplete feature applied to them. Is ...

Can you explain the different types of dynamic page props available in a Next.js application?

Is there a specific type available in Next.js 14 that I can use to replace the "any" type in the TypeScript code snippet below, for my dynamic route? export default async function DetailProduct({ params }: any) { const { imageAddress, title, price } = ...

Error 404 in Angular HTTP Request

I'm encountering a 404 error while attempting to send a post request, along with a 'possibly unhandled rejection' error. Given my limited experience with Angular, any advice would be greatly appreciated. I've gone through the documentat ...