Retrieve a mapping of keys from a generic object structure in TypeScript

I am trying to extract the key map from an object, and although I have created a function for this purpose, TypeScript is not happy with it. How can I resolve this issue without using acc: any?

const origin = {
  a: 1,
  b: 'string',
  c: () => {}
};

function getObjKeyMap<T>(obj: T) {
  return Object.keys(obj).reduce((acc, k) => {
 /* Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
  No index signature with a parameter of type 'string' was found on type '{}'.ts(7053) */
    acc[k] = k;
    return acc;
  }, {});
}

const keyMap = getObjKeyMap(origin);

Answer №1

Can you identify the type of object that reduce utilizes for the accumulator?

const originObj = {
  a: 1,
  b: 'string',
  c: () => {}
};

function getObjKeyMap<T>(obj: T) {
  return Object.keys(obj).reduce((acc, k) => {
    acc[k] = k;
    return acc;
  }, {} as Record<string, string>);
}

// or

function getObjKeyMap1<T>(obj: T) {
  return Object.keys(obj).reduce((acc: Record<string, string>, k: string) => {
    acc[k] = k;
    return acc;
  }, {});
}

const keyMap = getObjKeyMap(originObj);

Check TypeScript Playground here

Yet, there might be a more efficient solution available. It is possible to declare a function like this:

function getObjKeyMap<T, K extends keyof T>(obj: T): Record<K, K>

Typescript can then specify that

getObjectMap({a: 1, b: 'string', c: () => {}}
will produce {a: "a", b: "b", c: "c"}.

This approach seems more optimal:

const originObj = {
  a: 1,
  b: 'string',
  c: () => {}
};

type KeyMap<T> = {
  [key in keyof T]: key
};

function getObjKeyMap<T>(obj: T): KeyMap<T> {
  return Object.keys(obj).reduce((acc, k) => ({...acc, k: k}), {} as KeyMap<T>);
}

const keyMap = getObjKeyMap<typeof originObj>(originObj);

Explore TypeScript Playground here

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

Next js is throwing an error because it cannot accept objects as a React child. Instead, it found an error message stating "Response not successful: Received status code 401."

This app showcases Github issues by utilizing the graphql API. After finishing the app, I encountered an error without making any changes. The technologies used for this project include Next.js, Typescript, Material UI, Tailwind CSS, and GraphQL. https: ...

Exposing the method to the outside world by making it public in

I have a situation where I have a base class with a protected method called foo, and a child class that needs to make this method publicly accessible. Since this method will be called frequently, I am looking for a more efficient solution to avoid unnecess ...

Using TypeScript with Vue to Retrieve Information from a Form

Currently, I am attempting to retrieve data from a form in Vue using TypeScript. However, when declaring the data that I intend to use with this form, it seems to be posted on the fields as shown in this screenshot: message getting posted. I am unsure ho ...

Share information by including the provider within the @component declaration in Angular

I am looking to explore a new method of passing data using providers directly within the component itself. For instance, I am curious if there is a way to pass a variable from one component to another without relying on routing or other traditional methods ...

Issue: Using the command 'typings search' successfully locates a package, however, when attempting to install it using 'typings install', the process fails

I am currently attempting to install the Google Auth2 typings using 'typings': > typings search gapi.auth2 This command returns: NAME SOURCE HOMEPAGE DESCRIPTION VERSIONS UPDATED gapi.auth2 d ...

TypeScript's reliance on dependent types

Is it possible to implement this functionality using TypeScript? There exist objects that define various "actions". export interface IAction { action: string; data: any; otherParam1: number; otherParam2: number; } The 'action' p ...

The error TS2300 arises from the duplicate identifier 'PropertyKey' found in the node_modules/@types/core-js/index.d.ts file

I am encountering errors in the file node_modules/@types/core-js/index.d.ts while using Visual Studio Code IDE: After running npm start to serve the application, the following errors are displayed: (list of errors here) This is how my tsconfig.json ...

What is the connection between tsconfig.json and typings.json files?

I recently acquired a .NET MVC sample application that came with Angular2-final. Within the project, I noticed a typings.json file at the root and a tsconfig.json file in the ng2 app directory. What is the connection between these two files? Is this the mo ...

Error in Nestjs Swagger: UnhandledPromiseRejectionWarning - The property `prototype` cannot be destructed from an 'undefined' or 'null' object

Currently, I am in the process of developing a Nestjs REST API project and need to integrate swagger. For reference, I followed this repository: https://github.com/nestjs/nest/tree/master/sample/11-swagger However, during the setup, I encountered the foll ...

TypeScript maintains the reference and preserves the equality of two objects

Retrieve the last element of an array, make changes to the object that received the value, but inadvertently modify the original last position as well, resulting in both objects being identical. const lunchVisit = plannedVisits[plannedVisits.length ...

Using *ngFor to iterate through a nested collection in an Angular 2 application

I'm currently working on a challenge involving drilling down to iterate over an array within another collection of arrays within an Angular 2 application. To start off, I have set up my component to subscribe to an observable in the ngOnInit lifecycle ...

Exploring an array in Angular 2 using TypeScript

Just starting out with typescript and angular2 and working through some issues. I have a form that needs to display results from an array of changing items, so I don't know the exact index of each result. Here is my scenario: In my form.html file: ...

I have a quick question: What is the most effective method for creating PDF templates with Angular and .NET 6, specifically for designs that feature heavy

Seeking the optimal solution for creating PDF templates using Angular and .NET 6? Specifically looking to design templates that heavily feature tables. In my exploration of efficient PDF template creation with Angular and .NET 6, I ventured into using pdf ...

In Angular and Typescript, adjusting the index in one dropdown will automatically update the selected option in another dropdown

I'm a newcomer to Angular and I could use some assistance with the following requirement: In my Angular template, I have two dropdowns. I want the selection in one dropdown to automatically reflect in the other dropdown. Both dropdowns pull their val ...

crafting connections in 3D using TypeORM (ORM)

I attempted to construct a database schema involving users, groups, documents, and permissions. Users can be part of multiple groups Groups can have multiple users Users can possess permissions for documents Groups can have permissions for documents Perm ...

Issue with the recursive function in javascript for object modification

I have all the text content for my app stored in a .json file for easy translation. I am trying to create a function that will retrieve the relevant text based on the selected language. Although I believe this should be a simple task, I seem to be struggl ...

Can you provide guidance on how to divide a series of dates and times into an array based

Given a startDate and an endDate, I am looking to split them into an array of time slots indicated by the duration provided. This is not a numerical pagination, but rather dividing a time range. In my TypeScript code: startDate: Date; endDate: Date; time ...

Set the default value for a form control in a select dropdown using Angular

I've been struggling to figure out how to mark an option as selected in my select element, but I haven't had any luck. I've tried multiple solutions from the internet, but none of them seem to be working for me. Does anyone out there have ...

Attempting to create a login feature using phpMyAdmin in Ionic framework

Currently, I am in the process of developing a login feature for my mobile application using Ionic. I am facing some difficulties with sending data from Ionic to PHP and I can't seem to figure out what the issue is. This is how the HTML form looks li ...

The noUnusedLocal rule in the Typescript tsconfig is not being followed as expected

I am currently working on a project that utilizes typescript 3.6.3. Within my main directory, I have a tsconfig.json file with the setting noUnusedLocals: true: { "compilerOptions": { "noUnusedLocals": true, "noUnusedParameters": true, }, ...