What is preventing me from accessing a JavaScript object property when using a reactive statement in Svelte 3?

Recently, while working on a project with Svelte 3, I encountered this interesting piece of code:

REPL:

<script lang="ts">
  const players = {
    men: {
      john: "high",
      bob: "low",
    },
  };

  // const player = "bob"
  $: player = "bob";

  const test = players.men[player];

  console.log(test); //prints undefined
</script>

{player} //bob
{test} //undefined

Interestingly, Typescript raised an error in my case:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ john: string; bob: string; }'.
  No index signature with a parameter of type 'string' was found on type '{ john: string; bob: string; }'.ts(7053)

However, when I modified the code to const player = "bob", everything started working fine. It's quite intriguing!

Ever wondered why?

Answer №1

Using a random string to access an object can be unsafe, hence the compiler's complaint. The reason no complaint arises when using const is that a constant string literal is determined at compile time, making it immutable at runtime and therefore safe for the compiler to handle. There are ways to work around this issue, with one of the simplest (though not entirely secure) methods being a cast:

  const players = {
    men: {
      john: "high",
      bob: "low",
    },
  };

  // const player = "bob"
  let player = "bob";

  const test = players.men[player as keyof typeof players.men];

Alternatively, there might be a more secure approach with the Svelte feature you are attempting to utilize. In similar scenarios in TypeScript, I often use string literals or enums to ensure that the compiler prevents me from encountering unexpected undefined:

enum Males {
  JOHN = "john",
  BOB = "bob"
}

const players: {
  men: {
    [key in Males]: string;
  }
} = {
  men: {
    john: "high",
    bob: "low",
  },
};

const test2 = players.men[Males.JOHN];

Playground

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

Utilizing a loaded variable containing data from an external API request within the useEffect() hook of a React component

Essentially, I have an API request within the useEffect() hook to fetch all "notebooks" before the page renders, allowing me to display them. useEffect(() => { getIdToken().then((idToken) => { const data = getAllNotebooks(idToken); ...

Creating a dynamic TypeScript signature that includes an optional argument

For some unknown reason, I am attempting to implement a reduce method on a subclass of Map: const nah = Symbol('not-an-arg'); class MapArray<A, B> extends Map<A, B> { reduce<T = [A, B]>(f: (prev: T, next: [A, B]) => any ...

Prisma Hack: excluding properties in type generation

EDIT hiding fields in the TypeScript definitions may pose a hidden danger: inaccessible fields during development with intellisense, but accidentally sending the full object with "hidden" fields in a response could potentially expose sensitive data. While ...

Retrieve a list of class names associated with a Playwright element

Can anyone suggest the best method to retrieve an array of all class names for an element in Playwright using TypeScript? I've searched for an API but couldn't find one, so I ended up creating the following solution: export const getClassNames = ...

Type of result from a function that returns a linked promise

In my class, I have a method that returns a chained promise. The first promise's type is angular.IPromise<Foo>, and the second promise resolves with type angular.IPromise<Bar>. I am perplexed as to why the return type of doSomething is an ...

Resolving Node.js Absolute Module Paths with TypeScript

Currently, I am facing an issue where the modules need to be resolved based on the baseUrl so that the output code is compatible with node.js. Here is my file path: src/server/index.ts import express = require('express'); import {port, database ...

Trouble with implementing a custom attribute directive in Angular 4 and Ionic 3

Hello, I am currently working on implementing a search input field focus using a directive that has been exported from directives.module.ts. The directives.module is properly imported into the app.module.ts file. However, when attempting to use the direc ...

The TypeScript error message is saying that it cannot find the property 'push' of an undefined value, resulting in a error within the

Issue: Unable to access property 'push' of undefined in [null]. class B implements OnInit { messageArr: string[]; ngOnInit() { for(let i=0; i<5; i++) { this.messageArr.push("bbb"); } } } ...

Working with TypeORM to establish two foreign keys pointing to a single primary key in a table

For my project, I am looking to establish bi-directional ManyToOne - OneToMany relationships with two foreign keys that reference the same primary key. Specifically, I have a 'match' table that includes two players from the 'player' tab ...

Integrate incoming websocket information with state management in React

I am facing a challenge in creating a timeseries plot with data obtained from a websocket connection. The issue arises when new values overwrite the previously stored value in the state variable. const [chartData, setChartData] = React.useState(null) Cu ...

When integrating Bootstrap 5 into a SvelteKit app.html file, a "File Not Found" error may be triggered

I successfully integrated Bootstrap 5 using style and script tags in my app.html file, but I'm encountering an error with Vite indicating that certain files are not found. Any suggestions on how to resolve this issue? Error message: Error: Not foun ...

Error: User authentication failed: username: `name` field is mandatory

While developing the backend of my app, I have integrated mongoose and Next.js. My current challenge is implementing a push function to add a new user to the database. As I am still relatively new to using mongoose, especially with typescript, I am followi ...

Using Jest and TypeScript to mock the return value of react-oidc-context

For our project, we utilize react-oidc-context to handle user authentication using oidc-client-ts under the hood. The useAuth function provided by react-oidc-context gives us access to important information such as isAuthenticated, isLoading, and the auth ...

Using TypeScript and Node.js with Express; I encountered an issue where it was not possible to set a class property of a controller using

I have a Node application using Express that incorporates TypeScript with Babel. Recently, I attempted to create a UserController which includes a private property called _user: User and initialize it within the class constructor. However, every time I ru ...

"Exploring the dynamic duo of Angular2 and ng2Material

I am currently facing an issue with the styling in my code while using ng2Material with Angular2. First: A demonstration of Material style functioning properly can be seen in this plunker. When you click on the button, you will notice an animation effect. ...

Currently, I am attempting to implement password strength validation using Angular

Looking for a way to implement password strength validation in Angular? You may encounter an error message like this: NullInjectorError: No provider for password strength! in the passwordstrength.ts file HTML <div class="validation_errors t ...

Setting up the environment variable for ApolloClient to be utilized in server-side rendering for continuous integration/continuous deployment involves following a specific

My apolloClient is configured as follows: /** * Initializes an ApolloClient instance. For configuration values refer to the following page * https://www.apollographql.com/docs/react/api/core/ApolloClient/#the-apolloclient-constructor * * @returns Apoll ...

Generate a fresh array by filtering objects based on their unique IDs using Angular/Typescript

Hey there, I am receiving responses from 2 different API calls. Initially, I make a call to the first API and get the following response: The first response retrieved from the initial API call is as follows: dataName = [ { "id": "1", ...

Enhance user experience with Angular Material and TypeScript by implementing an auto-complete feature that allows

Currently facing an issue with my code where creating a new chip triggers the label model to generate a name and ID. The problem arises when trying to select an option from the dropdown menu. Instead of returning the label name, it returns an Object. The ...

Date input using manual typing format

I've implemented the ng-pick-datetime package for handling date selection and display. By using dateTimeAdapter.setLocale('en-IN') in the constructor, I have successfully changed the date format to DD/MM/YYYY. However, I'm facing an iss ...