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

"Navigate with ease using Material-UI's BottomNavigationItem and link

What is the best way to implement UI navigation using a React component? I am currently working with a <BottomNavigationItem /> component that renders as a <button>. How can I modify it to navigate to a specific URL? class FooterNavigation e ...

Utilizing Enum Lowercase as Index Key Type in TypeScript

Is there a way in TypeScript to use the lower case of an enum as an index key type? I have an enum defined as: export enum NameSet { Taxi = 'Taxi', Bus = 'Bus', Empty = '', } I want to define an object with keys based o ...

Subscription Code Incrementally Triggering Upon Each Component Load

Within the initialization of my component, I have the following code: public Subscription: Subscription; ngOnInit() { this.subscription = this.myService.currentData.subscribe( dataReceived => { this.data = dataReceived; this.useDa ...

Error: The function $compile does not exist

Currently, I am working on developing an AngularJS directive using TypeScript. While testing my code in the browser, I encountered the following error: TypeError: $compile is not a function at compileComponent.js:14 Interestingly, the TypeScript compiler ...

TS1055 occurs when utilizing async/await with a custom type alias

I defined a custom type alias: export type ActivationPromise = Promise<void>; I have created the following two functions: async function derp(): ActivationPromise { await test(); } function test(): ActivationPromise { return Promise.resol ...

Why am I encountering an issue while trying to access req.user.id?

Having set up passport authentication on my express, node project, I encountered an error when trying to access req.user. The error message displayed is Property 'id' does not exist on type 'User'.ts(2339). Below is the relevant code sn ...

Angular - Loading images on the fly

After scouring numerous resources, I couldn't find a resolution to my issue. For your information, I am utilizing ASP.net Core 2.0's default angular project In the process of developing an Angular application, I am faced with the challenge of ...

Is there a way for me to implement a "view more posts" button on

I need help figuring out how to hide the "Show More" button when there are no posts. I have created a showLoad function and an isLoad state variable, but I'm unsure of how to implement this. The button display logic is dependent on the isLoad state. ...

Guide to Injecting Services with Dependencies in Angular 2 (Using Ionic 2/Angular 2/Typescript)

As part of my project, I am developing a sample application that connects to a websocket server in Ionic 2 using Typescript. You can find the repository here. The main requirement is to establish the websocket connection when the application starts up. T ...

The parameter type cannot be assigned to an array type of 'IAulasAdicionais[]'

I am facing a problem in my application that I need help solving. The issue lies within my code, and I have included some prints of the error below: Mock data: "AulasAdicionais": [ { "Periodo": "1", "Hora ...

Guide to executing various datasets as parameters for test cases in Cypress using Typescript

I am encountering an issue while trying to run a testcase with multiple data fixtures constructed using an object array in Cypress. The error message states: TS2345: Argument of type '(fixture: { name: string; sValue: string; eValue: string}) => vo ...

`The utilization of a collective interface/data type within an Angular application`

I created a HeaderComponent that requires an object with the structure of {title: string, short_desc: string} as its input property. @Component({ selector: 'header', templateUrl: './header.component.html', styleUrls: ['./hea ...

Tips for modifying the type definition of a third-party library in a Vue project built with Create-Vue

After updating the Cesium library in my Vue project, I encountered some errors. This is the code snippet: camera.setView({ destination, orientation: { heading, pitch } }) The error message reads: Type '{ heading: number; pitch: number; }' i ...

Delivering static HTML routes in a React App using Typescript

I am working on a React app with functional components, and everything is working perfectly with its own CSS. Now, I have a separate static HTML file (FAQ) with its own CSS and design that I want to incorporate as a new route at /FAQ. I don't want th ...

Array of colors for Wordcloud in Angular Highcharts

I am currently utilizing Angular Highcharts 9.1.0 and facing an issue with generating a word cloud that incorporates specific colors. Despite including color values in the array, they do not seem to be applied as intended. Take a look at the code snippet b ...

Generate a blueprint for a TypeScript interface

In my coding project, I've been noticing a pattern of redundancy when it comes to creating TypeScript interfaces as the code base expands. For example: interface IErrorResponse { code: number message: string } // Feature 1 type FEATURE_1_KEYS = ...

Is it possible that React.createElement does not accept objects as valid react children?

I am working on a simple text component: import * as React from 'react' interface IProps { level: 't1' | 't2' | 't3', size: 's' | 'm' | 'l' | 'xl' | 'xxl', sub ...

Node's TypeScript parser loses the order of same name-tags when converting XML to JSON

I've experimented with xml2js and fast-xml-parser and received similar results from both (in different formats, but that's not the focus here) This specific example is from fast-xml-parser Here's the XML data: <test version="1" ...

What are the methods to determine the cause of ESLint's slow performance?

Looking to analyze the performance of ESLint in my application. So far, I have only come across one profiling tool provided by ESLint which is the TIMING=1 environment variable. Combining this with DEBUG=eslint:cli-engine allows me to see timing results pe ...

Can I exclusively utilize named exports in a NextJS project?

Heads up: This is not a repeat of the issue raised on The default export is not a React Component in page: "/" NextJS I'm specifically seeking help with named exports! I am aware that I could switch to using default exports. In my NextJS ap ...