"Using an indexer in TypeScript allows for direct access to object properties by simply specifying the key within

I have a requirement to access an object property using a string as the key

interface MyObject {
  prop1: string;
  prop2: string;
  prop3: string;
  prop4: string;
  prop5: string;
} 

let initialValues: MyObject;

//I initialize some properties
initialValues = {
    prop1: 'xxxx',
    prop2: 'yyyy'
}

//I set values for additional (existing) properties 
[3,4,5,6].map(i => {
    initialValues[`prop${i}`] = 'zzzz';
});

Upon running this code, I encountered the following error message:

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'MyObject'

Answer №1

When working with [3,4,5,6], Typescript automatically assumes the widest possible type as string[]. To narrow it down, you can use as const.

([3,4,5] as const).map(i => {
initialValues[`prop${i}`] = 'zzzz';});

Take a look at this code in the Typescript playground.

Answer №2

Typescript struggles to recognize that the values you provide are valid keys of the interface, posing a limitation.

Your best option is to utilize type assertion, although keep in mind that it does not ensure type safety; instead, you are essentially confirming to TS that the type is accurate:

interface MyObject {
  prop1: string;
  prop2: string;
  prop3?: string;
  prop4?: string;
  prop5?: string;
} 

let initialValues: MyObject = {
  prop1: 'x',
  prop2: 'y'
}

let ans = [3,4,5,6].map(i => {
    initialValues[`prop${i}` as keyof MyObject] = 'zzzz';
});

It's important to note that TS may not automatically discern that 6 won't cause any issues here.

Link

Answer №3

To inform TypeScript that a property will be part of the object, utilize a type assertion:

interface MyObject {
  prop1: string;
  prop2: string;
  prop3: string;
  prop4: string;
  prop5: string;
} 

let initialValues: MyObject;

//Setting a property
initialValues = {
    prop1: 'xxxx'
    prop2: 'yyyy'
}

//Assigning values to existing properties 
[3,4,5,6].map(i => {
    initialValues[`prop${i}` as keyof MyObject] = 'zzzz';
});

TypeScript Playground

However, exercise caution with this approach! TypeScript does not verify if the property is valid, leading to potential loss of runtime type safety. TypeScript remains silent in such cases.

If you are aware of the possible array values, specifying them will enable TypeScript to recognize valid keys:

interface MyObject {
  prop1: string;
  prop2: string;
  prop3?: string;
  prop4?: string;
  prop5?: string;
} 

let initialValues: MyObject;

//Setting a property
initialValues = {
    prop1: 'xxxx',
    prop2: 'yyyy'
};

//Assigning values to existing properties 
let values: (3 | 4 | 5 | 6)[] = [3, 4, 5, 6];
values.map(i => {
    initialValues[`prop${i}`] = 'zzzz';
});

TypeScript Playground

In this scenario, TypeScript only flags prop6 for invalidity. Opt for this method whenever feasible to maintain type safety.

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

Issue with Angular 5 EventEmitter causing child to parent component emission to result in undefined output

I've been trying to pass a string from a child component to its parent component. Child Component: //imports... @Component({ selector: 'child', templateUrl: './child.component.html', styleUrls: ['./child.c ...

Issue with TagCloud functionality when deployed on Vercel platform

Everything functions perfectly on my local machine, but once deployed to Vercel, the display disappears. I've double-checked the text, container, and TagCloud - all showing the correct responses. I even tried uninstalling and reinstalling TagCloud wit ...

Using Typescript to assign a custom object to any object is a powerful feature

I am attempting to organize table data by utilizing the code found at https://github.com/chuvikovd/multi-column-sort. However, I am unsure of how to pass a custom object to the SortArray[T] object. The structure of my custom object is as follows: const ob ...

Failure to invoke Jest Spy

Currently, I am attempting to conduct a test utilizing the logging package called winston. My objective is to monitor the createlogger function and verify that it is being invoked with the correct argument. Logger.test.ts import { describe, expect, it, je ...

Can the return type of a function be utilized as one of its argument types?

When attempting the following code: function chain<A, B extends (input: A, loop: (input: A) => C) => any, C extends ReturnType<B>> (input: A, handler: B): C { const loop = (input: A): C => handler(input, loop); return loop(input) ...

Exploring the functionality of this TypeScript code: What's the distinction between { [key: string]: string }[] and { prop1: string, prop2: string }[]

Below is the code I am currently working with: get tags(): { [key: string]: string }[] { let tags: { [key: string]: string }[] = []; if(this.tags) { Object.keys(this.tags).forEach(x => { tags.push({ prop1: this.tags[x], prop2: g ...

Execute environment validation on server during `next build` command

I have a src/config/server/ts file that contains the following code: 'use server'; import zod from 'zod'; if (typeof window !== 'undefined') { throw new Error('env should not be imported on the frontend!'); } co ...

Tips for saving an Angular project for offline use

I have created a basic form for a family member to use in their medical practice, and I want to make it functional offline. The form simply captures data and displays it, with no need to send or store the information anywhere. What would be the most effect ...

Remember to always call "done()" in Typescript + Mocha/Chai when dealing with async tests and hooks. Additionally, when returning a Promise, make sure it resolves correctly

It seems like I'm facing an old issue that I just can't seem to resolve, despite trying everything in my power. The error message reads: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Pro ...

The module `perf_hooks` could not be resolved

Trying to integrate perf_hooks library from the nodeJS Performance API into my React Native project has been quite a challenge. Here's the snippet of code I've been working with: import {performance} from 'perf_hooks'; export const mea ...

How can I integrate the jQuery Plugin Mapael with Angular 5?

While exploring various methods that tackled the issue of integrating jQuery Plugins, I decided to start with the fundamentals. To begin with, I installed the jQuery plugin: npm i jquery Next, I included the TypeScript definition: npm install -d @types ...

Implementing Styled API in TypeScript with props: A Comprehensive Guide

I'm currently working on styling a component using the new styled API, not to be confused with StyleComponents. const FixedWidthCell = styled(TableCell)((props: { width: number }) => ({ width: props.width || 20, textAlign: "center", })) The i ...

Issue with VueJS 2 and TypeScript: computed value unable to recognize property specified in data object

When creating the following component: <template lang="html"> <div> <p>{{ bar }}</p> </div> </template> <script lang="ts"> import Vue from 'vue'; export const FooBar = Vue.ex ...

Travis CI's TypeScript build process detects errors before Mocha has a chance to catch them

Instead of a bug, the TypeScript compiler is doing its job but causing my Travis builds to fail. In my package, I have a function named completeRound which accepts a number as its first argument and 3 optional arguments. Since it's in TypeScript, I s ...

Improving the process of class initialization in Angular 4 using TypeScript

Is there a more efficient method to initialize an inner class within an outer class in Angular 4? Suppose we have an outer class named ProductsModel that includes ProductsListModel. We need to send the ProductId string array as part of a server-side reque ...

Enabling Javascript compilation while overlooking typescript errors

Currently, I am working in VS Code with create-react-app using TypeScript. Whenever there are type errors, they show up in the browser and prevent compilation by TypeScript. I am looking for a way to only see these errors in the Google console and termin ...

If a generic string argument is not specified as a string literal, it will not be narrowed unless it is the first argument

When the following code is executed, it works as intended and we can see that the arg variable is a string literal: const foo = <T extends string = string>(arg: T) => {}; foo('my string'); // const foo: <"my string">(arg ...

A Defer statement in TypeScript that mimics Go's functionality

Is there an equivalent to Go's Defer statement in TypeScript? I find it tedious to write cleanup code in various parts of a function. Searching for a simpler alternative. I tried searching on Google, but couldn't locate any relevant information ...

Receiving NULL data from client side to server side in Angular 2 + Spring application

I'm currently working on a project that involves using Angular 2 on the client side and Spring on the server side. I need to send user input data from the client to the server and receive a response back. However, I'm encountering an issue where ...

Tips on adding TypeScript annotations to an already existing global function

I'm contemplating enhancing an existing project by incorporating TypeScript type annotations. Struggling to supply an external declaration file for a straightforward example: app.ts: /// <reference path="types.d.ts"/> function welcome (person ...