Navigating an object in TypeScript: the right approach

Curious if there might be a bug in TypeScript? Just seeking clarification on whether my code is incorrect or if there is an actual issue with the language.

interface Something {
    key1: string;
    key2: number;
    key3: boolean;
}

const someObject: Something = {
    key1: '123',
    key2: 123,
    key3: false
}

for (const key in someObject) {
    console.log(someObject[key]); // TS error
}

Note: Not looking for workarounds as this code works fine for me. Simply trying to determine if I am making an error or if TypeScript has a potential bug.

for (const [key, value] of Object.entries(someObject)) {
    console.log(key, value);
}

or

for (const key in values) {
    console.log(key, values[key as keyof DirectDepositDTO]);
}

I understand that the type of key may be string, but shouldn't it ideally be keyof Something?

TypeScript Playground Link

P.S. The question is marked as a duplicate, however, I am not in need of a solution right now as I already have one. What I seek to clarify is if there might be a bug in TypeScript. Using for (const key in someObject) { should automatically mean that key will represent keyof Something. There should be no requirement to redefine the types.

Answer â„–1

There are multiple approaches you can take.

If you prefer using a for .. in loop, one option is to enable TS to work with indexed properties:

interface Something {
    key1: string;
    key2: number;
    key3: boolean;
}

type Values<T> = T[keyof T]
type MakeIndexed<T> = T & { [prop: string]: Values<T> }
type SomethingIndexed = MakeIndexed<Something>

const someObject: SomethingIndexed = {
    key1: '123',
    key2: 123,
    key3: false
}

for (const key in someObject) {
    const x = someObject[key] // Values<Something>
    const isString = someObject.key1 // string

    console.log(someObject[key]);
}

Alternatively, you can opt for a more functional approach without additional utility types by utilizing type casting:

    const someObject: Something = {
        key1: '123',
        key2: 123,
        key3: false
    }

    // Functional programming method with clearer types
    const keys2 = (Object.keys(someObject) as Array<keyof typeof someObject>).forEach(key => {
        const result = someObject[key]; // string | number | boolean
    })

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

Tips for utilizing mergeWith with Subjects in an Angular application

Objective: Creating a Combined Filter with 3 Inputs to refine a list Conditions: Users are not required to complete all filters before submission The first submit occurs when the user inputs data Inputs are combined after more than one is provided Appro ...

Resolving circular dependencies caused by APP_INITIALIZER

My AuthenticationService is responsible for loading the AngularFirestore and is loaded in the RootComponent. All app modules are lazily loaded within the RootComponent (which contains the main router-outlet). However, several sub-modules also load the Ang ...

React's .map is not compatible with arrays of objects

I want to retrieve all products from my API. Here is the code snippet for fetching products from the API. The following code snippet is functioning properly: const heh = () => { products.map((p) => console.log(p.id)) } The issue ari ...

What is the best way to iterate through all class properties that are specified using class-validator?

I have a class defined using the class-validator package. class Shape { @IsString() value?: string @IsString() id?: string } I am trying to find a way to retrieve the properties and types specified in this class. Is there a method to do s ...

Exploring .ENV Variables using Angular 2 Typescript and NodeJS

After completing the Angular2 Quickstart and tutorials, I'm now venturing into connecting to a live REST Api. I need to include authentication parameters in my Api call, and from what I've gathered, it's best practice to store these paramete ...

Enabling the "allowUnreachableCode" Compiler Option in Visual Studio 2015 Triggers "JsErrorScriptException (0x3001)" Issue

We've implemented TypeScript in our Visual Studio 2015 (Update 2) setup for a non-ASP.Net project consisting of pure HTML and JavaScript. In order to disable the 'allowUnreachableCode' option, we made adjustments in the tsconfig file. It&apo ...

Discovering the method to access a local function within a static function in Javascript ES6 (ES2015) or Typescript

Is there a way to access the non-static "foo2" method from inside the static "bar" method? So far, I'm only able to access the "foo1" and "foo3" methods. Can anyone provide guidance on how to achieve this? let foo1 = () => { alert('foo1†...

What methods are available for altering state in Server Actions in NextJS 13?

Struggling to Implement State Change in NextJS 13 Server Actions I have encountered a challenge with altering state within the execution of server actions in NextJS 13. The scenario involves an actions.ts file located at the root of the app directory. Cur ...

What causes TypeScript 3.7.5 to trigger an error while typing a function that accepts an array as a parameter?

I'm facing a perplexing compiler error while trying to define a function that requires an array as its sole argument. Below is a concise scenario to reproduce the issue: http://www.example.com import React from 'react' type FooProps = { ...

Having difficulty in utilizing localStorage to update the state

I've attempted to log back in using the stored credentials, however it's not working despite trying everything. The dispatch function is functioning properly with the form, but not when accessing localStorage. App.tsx : useEffect(() => { ...

Define an object by extracting properties from an array of objects

Is there a way to refactor this code to remove the need for explicit casting? type A={a:number}; type B={b:string}; let a:A={a:0}; let b:B={b:''}; function arrayToObject<T>(array:T[]):T { return array.reduce((r,c) =>Object.assign ...

The value of form.formGroup is not equivalent to the output of console.log(form)

Having an issue here. When I send a Form to a component, If I use console.log(form), it displays the object correctly. However, when I check the form in the console, the form.formGroup.value looks fine (e.g. {MOBILE0: 'xxx', PHONE0: 'xxx&ap ...

I am attempting to gather user input for an array while also ensuring that duplicate values are being checked

Can someone assist me with the following issue: https://stackblitz.com/edit/duplicates-aas5zs?file=app%2Fapp.component.ts,app%2Fapp.component.html I am having trouble finding duplicate values and displaying them below. Any guidance would be appreciated. I ...

Is it possible to use v-if in conjunction with a style tag to specify a different source file? Alternatively, is there a more efficient method I

I attempted the example provided below, but unfortunately, it did not function as expected. The reason behind my endeavor is that adding numerous modifiers (--tuned) to achieve the desired outcome seemed impractical. Therefore, I decided to try and link ...

Utilize Sequelize's cascade feature within your application

I'm currently building a web application using sequelize and typescript. In my database, I have three tables: WfProjectObject, which is connected to WfProject, and WfStep, also linked to WfProject. My goal is to include WfStep when querying WfProject ...

Can an attribute be assigned to an Angular host element without specifying a value?

Exploring the concept of host binding on the input element's readonly attribute, aiming to add the attribute without assigning any value. Even though HTML specifications state that assigning a value may not make a difference as long as the attribute i ...

Running two different wdio.config.js files consecutively

Is it possible to run two wdio.config.js files with different configurations, one after another? Here is how the first configuration file is defined in the code: const { join } = require('path'); require('@babel/register') exports.co ...

Connect an Observable to the template with async binding

I've been attempting to link an Observable to a template variable in Angular using the following code: [class.active]="isBookmarked$ | async" During the ngOnInit function, I initialize the Observable: var promise = this.cacheService.getItem(this.bo ...

Guide on how to specify the return type for useMutation in the 'react-query' library

Here is the code snippet provided: const setFriendCode = (data: Params) => api({ data }) const [mutateSetFriendCode, state] = useMutation<Response, Params>( setFriendCode ) An issue arises with the type of parameters in the code. The compiler ...

Encountered an issue in Angular 2 when the property 'then' was not found on type 'Subscription'

I have been attempting to call a service from my login.ts file but I am encountering various errors. Here is the code snippet in question: login.ts import { Component } from '@angular/core'; import { Auth, User } from '@ionic/cloud-angular ...