What is the best way to convert a tuple containing key/value pairs into an object?

How can the function keyValueArrayToObject be rewritten in order to ensure that the type of keyValueObject is specifically {a: number; b: string}, instead of the current type which is {[k: string]: any}?

const arrayOfKeyValue = [
  {key: 'a', value: 1},
  {key: 'b', value: 'z'},
];

const keyValueArrayToObject = <const T extends readonly {key: PropertyKey; value: any}[]>(
  arr: T
) => {
  return Object.fromEntries(arr.map(o => [o.key, o.value]));
};

const keyValueObject = keyValueArrayToObject(arrayOfKeyValue);

Answer №1

To traverse through the union of element types in an array called arr, you can utilize key remapping in mapped types by indexing into each member of the union to access the key and value properties:

const keyValueArrayToObject = <const T extends readonly { key: PropertyKey; value: any }[]>(
  arr: T
) => {
  return Object.fromEntries(arr.map(o => [o.key, o.value])) as
    { [U in T[number] as U['key']]: U['value'] };
};

A type assertion is needed here because TypeScript does not strongly type Object.fromEntries().


Now let's test this with an example:

const arrayOfKeyValue = [
  { key: 'a', value: 1 },
  { key: 'b', value: 'z' },
] as const;

const keyValueObject = keyValueArrayToObject(arrayOfKeyValue);
/* const keyValueObject: {
    a: 1;
    b: "z";
} */

This output looks good, but there are some recommendations. Firstly, use a const assertion or similar on your array literal to ensure specific literal types for the keys and values. This will help TypeScript infer the correct types for your needs. If it's too specific, consider widening it manually or controlling the array literal types more precisely.

Playground link for code snippet

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

Adjust the color of an SVG icon depending on its 'liked' status

In my React/TypeScript app, I have implemented an Upvote component that allows users to upvote a post or remove their upvote. The icon used for the upvote is sourced from the Grommet-Icons section of the react-icons package. When a user clicks on the icon ...

Custom type checker that validates whether all properties of a generic object are not null or undefined

In an attempt to create a user-defined type guard function for a specific use-case, I am faced with a challenge: There are over 100 TypeScript functions, each requiring an options object. These functions utilize only certain properties from the object wh ...

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 ...

Troubleshooting problems with permissions when using the AWS IAM assumeRole function with session

Within my aws-cdk application, I am working on setting up a lambda function to assume a specific role and obtain credentials through aws-sts. These credentials need to include a tenant_id tag. AWS CDK Code: Role to be assumed: const pdfUserRole = new Rol ...

Combine two closely related functions into a single function

I'm dealing with two very similar functions: setEndTimesAndStartTimes(pricerules: PriceRule[], type: string) { this.endTimes = []; this.startTimes = []; pricerules.forEach(pricerule => { if (type === 'end') { ...

Is there a way to create a tuple property that can be called like a

I have a specific function in my code: function test(cb: Function | number) { let item = { height: 0} if(typeof cb === 'number') { item.height = cb; } if(typeof cb === 'object') { item.height = cb(); } } This function ...

I'm having trouble with Angular pipes in certain areas... but I must say, Stackblitz is truly incredible

Encountering this issue: ERROR in src\app\shopping-cart-summary\shopping-cart-summary.component.html(15,42): : Property '$' does not exist on type 'ShoppingCartSummaryComponent'. The error disappears when I remove the c ...

Should the null-forgiving operator be avoided when using `useRef`?

Is the following code snippet considered poor practice? const Component: React.FC<{}> = () => { const ref = React.useRef<HTMLDivElement>(null!); return <div ref={ref} />; } I'm specifically questioning the utilization of ...

Uncovering the perfect body proportions using Webpack and SystemJS

In the process of developing an Angular2 library that needs to work with both SystemJS and Webpack, I encountered a situation where I had to detect the height and width in pixels of the body tag to set dimensions for child tags. However, the behavior of An ...

Exploring the functionalities of React Native with react-hook-form and implementing them with TypeScript

I've been working on creating a custom Input component in react native using typescript for the react-hook-form library. type CustomInputProps = { name: any, control: any } const CustomInput: FC<CustomInputProps> = ({name, control, ...p ...

There is an issue with the property 'updateModf' in the constructor as it does not have an initializer and is not definitely assigned

When working with an angular reactive form, I encountered an issue. After declaring a variable with the type FormGroup like this: updateModf:FormGroup; , the IDE displayed an error message: Property 'updateModf' has no initializer and is not def ...

In the CallableFunction.call method, the keyword "extends keyof" is transformed into "never"

In the following method, the type of the second parameter (loadingName) is determined by the key of the first parameter. (alias) function withLoading<T, P extends keyof T>(this: T, loadingName: P, before: () => Promise<any>): Promise<void ...

The error message "The type 'MouseEvent' is non-generic in TypeScript" popped up on the screen

Having created a custom button component, I encountered an issue when trying to handle the onClick event from outside the component. I specified the parameter type for the onClickCallback as MouseEvent<HTMLButtonElement, MouseEvent>, which is typical ...

Embarking on your ABLY journey!

Incorporating https://github.com/ably/ably-js into my project allowed me to utilize typescript effectively. Presently, my code updates the currentBid information in the mongodb document alongside the respective auctionId. The goal is to link the auctionId ...

Testing React Components - The `useClient` function should only be used within the `WagmiConfig` component

In my Next.js app with TypeScript, Jest, and React testing library, I encountered an error while trying to test a component. The error message states that `useClient` must be used within `WagmiConfig`. This issue arises because the `useAccount` hook relies ...

Encountered an issue with ionViewDidLoad: The property 'firstChild' cannot be read as it is null

While working on an Ionic 2 App with Angular2 and Typescript, I encountered an issue when trying to pass a JSON to map for markers. Here is the link to the gist containing the code snippet I am facing an error that reads: view-controller.js:231 MapPage i ...

Challenges faced when using an array of objects interface in Typescript

I have initialized an array named state in my component's componentDidMount lifecycle hook as shown below: state{ array:[{a:0,b:0},{a:1,b:1},{a:2,b:2}] } However, whenever I try to access it, I encounter the following error message: Prop ...

Handling Promises in Angular 1 App using Typescript ES6/2015

Currently, I am working on an Angular 1.5 application that utilizes Typescript. My main concern is finding the most efficient way to handle ng.IPromise compared to Promise (ES6 promise). Personally, I would prefer to solely deal with the ES6 Promise type. ...

What is the most effective way to condense these if statements?

I've been working on a project that includes some if statements in the code. I was advised to make it more concise and efficient by doing it all in one line. While my current method is functional, I need to refactor it for approval. Can you assist me ...

Strategies for implementing classes in Typescript

I've been working on incorporating more classes into my project, and I recently created an interface and class for a model: export interface IIndexClient { id?: number; name?: string; user_id?: number; location_id?: number; mindbody_id?: nu ...