How can I properly type my object using generics if the Typescript code `let result: { [key: T[K]]: T } = {};` is not functioning as expected?

I am developing a function called keyBy that has a simple purpose.

The objective of this function is to transform an array of objects into an object, using a provided 'key string':

const arr = [{ name: 'Jason', age: 18 }, { name: 'Amy', age: 25 }];

console.log(keyBy(arr, 'name'));

// => { 'Jason': { name: 'Jason', age: 18 }, 'Amy': { name: 'Amy', age: 25 } }

Here is a basic implementation of the javascript function without typescript:

function keyBy(arr, key) {
  let result = {};

  arr.forEach(obj => {
    result[obj[key]] = obj;
  });

  return result;
}

Currently, I have a version of my `keyBy` function in typescript that is not compiling as expected:

function keyBy<T, K extends keyof T>(arr: T[], key: K): { [key: T[K]]: T } {

  // The error message states: An index signature parameter type must be 'string' or 'number'.

  let result: { [key: T[K]]: T } = {};

  arr.forEach(item => {
    result[item[key]] = item;
  });

  return result;
}

You can find a screenshot of the issue in my VSCode here:

https://i.sstatic.net/T62gB.png

How can I correctly type the `keyBy` function in typescript?

Answer №1

You can also achieve the same result in a different way:

export type Omit<A extends object, K extends keyof A> = Pick<A, Exclude<keyof A, K>>

type KeyOf<T extends Array<any>> = { [K: string]: Omit<T[number], 'name'> };

type Result = KeyOf<[{ name: 'a', attr: 42 }, { name: 'b', attr: 42}, {name: 'c', attr: 42}]>

The Omit utility function will return an interface without the specified key, which in this case is 'name'.

T[number] yields X when T is an array.

K will always be of type string since it's referring to an ordinary object.

Try it out on the playground

Answer №2

In order to utilize named key properties, it is necessary to employ in instead of ::

{ [key in K]: T }

Furthermore, ensure you are using K, which represents a string union type of property names, as opposed to T[K], which indicates the value of the property.

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

Using jQuery to dynamically add a value to a comment string

Is there a way to dynamically include tomorrow's start and end times in the message for the setupOrderingNotAvailable function if today's end time has passed? The current message states that online ordering will be available again tomorrow from 1 ...

What is the reason behind jQuery(this).css('background-image') returning the browser's URL?

There are three divs in the code snippet below. <div id="div#product_img_wrapper"> <div id="product_design1" class="timage" style="z-index: 20; background-image: url('');"></div> <div id="product_design2" class="tim ...

What is the purpose of the c() function in JavaScript?

I recently stumbled upon some interesting JavaScript code in the source of a web page: function fsb329142055() { var b=new Array(57,50,102,50,52,99,50,53,52,56,102,98,102,98,101,102,101,49,53,61,101,99,110,57,111,78,109,54,114,111,56,48,102,38,1 ...

Creating a network of lists by combining multiple arrays

I'm currently working on generating a comprehensive list of all possible combinations of multiple arrays. While I have experience in Matlab and understand loops and basic coding principles, I'm unsure of the most efficient method to compile these ...

Is there a way to retrieve the number of notifications that have not been seen or read from the API?

Is there a way to retrieve the unread or unseen count in PHP without relying on a real-time notifications JavaScript library? Typically, using a JavaScript library would provide the following information: "data": { "deleted": "array of activities or ...

How to retrieve every field value from a MySQL database using PHP

Could someone please explain how to retrieve all field values based on an array search? I currently have an array set up as follows: Here is a sample of my table: id content 1 zahr 2 hai . . . and so on I have an array $a containing the value ...

modify the tr element within a jQuery context

I am attempting to convert a "yes" to a select dropdown that allows users to choose between yes and no. The HTML structure is as follows: <tr> <td>text</td> <td>no (needs to be changed via JS)</td> <td><a href="#"&g ...

The function PageMethods is not recognized

On my webpage with a MasterPage, the master page contains the following code: <ajaxToolkit:ToolkitScriptManager ID="scriptManager" runat="server" AsyncPostBackTimeout="99999999" ...

I created a context to display the user's email upon logging in using Next.js and Firebase. However, an error occurred when attempting to show the email in the navbar

I keep encountering this issue while attempting to load the page Error: (0 , lib_AuthContext__WEBPACK_IMPORTED_MODULE_1_.useAuth) is not a function On a side note, signing in and signing up are functioning correctly AuthContext.js "use client" ...

Persistence of query parameters from old routes to new routes using vue-router

Whenever a query parameter called userId is present in a route within my application, I want the subsequent routes to also include this query parameter. Instead of manually modifying each router-link and router.push, I am looking for a solution using rout ...

Unable to use the res.send() function

I've been working on a Node.js project. Within the validate.js file, I have defined a class Validate with a static method validateTicket and exported the class at the end. validate.js file const request = require("request"); const config = { urlBas ...

What is the functionality of this.$eval in Vue.js?

During the process of updating an unfamiliar old script from version 0.11 to 2.5.4, an alert popped up stating: To address the warning message saying 'Replace this.$eval('reportData | reportFilter false') with a solution using normal Java ...

Confidently set up a proxy that is recursively nested and strongly typed

I have a collection of objects where I store various content for a user interface. Here is an example: const copy = { header: { content: 'Page Header' }, main: { header: { content: 'Content Subheader' }, body ...

Error: Unable to assign a value to the 'name' property of an undefined object after modifying input field data

I am currently working on developing a React application. The app includes a button labeled "Add" that, when clicked, adds multiple input fields to the screen. Each line of inputs also features a button marked "X" which allows users to remove that specific ...

Create a Typescript index signature that incorporates individual generic types for each field

Many times, the keys of a record determine its value. For instance: const record = { [2]: 5, ["string"]: "otherString", ["there is"]: "a pattern" } In these instances, each key of type K corresponds to the ...

What is the best way to insert a record into the rth column of the nth row in a table

In the table I'm working with, there are 6 columns and only 5 of them have data filled in. The last column is currently empty for all rows. I am now trying to populate the last column of each row with some data. Can someone guide me on how to use a f ...

Creating input fields dynamically within Yii2 framework

I'm currently facing a challenge with forms in Yii2. My objective is to design a form that includes three dropdown menus, inquiring about the user's preferred time(s) during the week. The first menu will focus on selecting days of the week, while ...

Laravel triggers a 'required' error message when all fields have been filled

As I attempt to submit a form using an axios post request in laravel, I encounter an issue with the validation of the name and age fields, along with an image file upload. Here is a breakdown of the form structure: Below is the form setup: <form actio ...

What is the best way to mandate the declaration or type of a function in TypeScript?

Let me present my dilemma: I am aiming to create a declaration file containing TypeScript function models. This file will be utilized by various individuals to build their own programs. To achieve this, I have crafted a def.d.ts file with a small example ...

When transforming a TreeMap into an array, does the array maintain the original order of the elements?

Is it true that regardless of the computer environment, if the same values are inputted into a TreeMap, the order of the data in the TreeMap will always be the same? I am curious to know if converting a TreeMap to an array using the specified method will r ...