Converting a mapped generic type into a union of tuples in TypeScript: A step-by-step guide

I'm currently in the process of developing a custom function similar to Object.entries, but I want to enhance its typing. My goal is to create a type that, given an object, can provide a strongly typed union of 2-tuples for that object's properties.

At present

export type Entries<T> = [keyof T, T[keyof T]][];

Entries<{first: number, second: string}> = ["first" | "second", number | string][]

My desired outcome

Entries<{first: number, second: string}> = ["first", number] | ["second", string][]

Answer №1

To implement a mapped type, utilize the syntax {[K in keyof T]: ...} to define and access its properties:

export type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T][];

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])[]

You can alternatively employ a distributive conditional type with a helper type alias for functionality:

type EntriesHelper<T, K> = K extends keyof T ? [K, T[K]] : never;
type Entries<T> = Array<EntriesHelper<T, keyof T>>;

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])

or opt for a method that utilizes inference in conditional types instead of a separate helper:

type Entries<T> = Array<
  keyof T extends infer K ? (K extends keyof T ? [K, T[K]] : never) : never
>;

type E = Entries<{ first: number; second: string }>;
// type E = (["first", number] | ["second", string])[]

While they yield identical results here, nuances may arise regarding optional properties or other edge cases, so proceed cautiously. Best of luck!

Link to code

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

How to retrieve a value from an Angular form control in an HTML file

I have a button that toggles between map view and list view <ion-content> <ion-segment #viewController (ionChange)="changeViewState($event)"> <ion-segment-button value="map"> <ion-label>Map</ion-label> & ...

Encountering a tsx-loader issue when integrating tsx with vuejs

I've been attempting to integrate TSX with Vuejs based on several blog posts, but I'm consistently encountering the error displayed below. I cloned a starter kit from GitHub and it worked fine, leading me to believe that there may be an issue wit ...

Guide for implementing props in a text area component using React and TypeScript

My react component has a sleek design: import { TextareaHTMLAttributes} from 'react' import styled from 'styled-components' const TextAreaElement = styled.textarea` border-radius: 40px; border: none; background: white; ` const T ...

"Using Angular and TypeScript to dynamically show or hide tabs based on the selected language on a website

When switching the language on the website, I want to display or hide a specific tab. If the language is set to German, then show the tab; if any other language is selected, hide it. Here's my code: ngOnInit(): void { this.translate.onLangChange.s ...

Throttle the asynchronous function to guarantee sequential execution

Is it possible to use lodash in a way that debounces an async function so it runs after a specified delay and only after the latest fired async function has finished? Consider this example: import _ from "lodash" const debouncedFunc = _.debounc ...

Having trouble halting the execution at specific checkpoints within an asp.net core project containing an angular 8.0 application located in a subfolder named ClientApp

Encountering difficulties stopping at breakpoints in an asp.net core project with an angular 8.0 app located in a subfolder within ClientApp. The app I need to set a breakpoint in is located at clientapp\apps\microsympan\app\src\ap ...

What types of modifications do ViewChildren and ContentChildren QueryLists keep an eye out for?

Imagine you come across the following lines of code: https://i.stack.imgur.com/7IFx1.png And then, in a different section, you stumble upon this code block: https://i.stack.imgur.com/qac0F.png Under what circumstances would () => {} be executed? Wha ...

Create an alternate name for a specific type of key within a nested record

There are three simple types available: const structureTypes = z.enum(["atom","molecule"]) const atomTypes = z.enum(["oxygen","hydrogen"]) const moleculeTypes = z.enum(["water","ammonia"]) The goal is to define a type for a cache where the keys correspond ...

Exploring the functionality of multiple checkboxes in Next.js 14, the zod library, shadcn/ui components, and react-hook

I'm currently working on a form for a client where one of the questions requires the user to select checkboxes (or multiple checkboxes). I'm still learning about zod's schema so I'm facing some challenges in implementing this feature. I ...

What is the most effective way to loop and render elements within JSX?

Trying to achieve this functionality: import React from 'react'; export default class HelloWorld extends React.Component { public render(): JSX.Element { let elements = {"0": "aaaaa"}; return ( ...

Building and executing an Angular 2 program on the Windows platform: Step-by-step guide

After successfully installing npm and related packages including TypeScript and Angular 2, I am encountering difficulties running Angular 2 in my browser on a Windows platform. Can someone provide a step-by-step guide to help me create and run Angular 2 ...

What purpose does the question mark (?) serve after a class name when invoking class methods in TypeScript?

One interesting element within my TypeScript code snippet is the presence of the statement row?.delete();. I'm curious about the significance of the question mark in this context. What would be the outcome if 'row' happened to be null? Ap ...

DOCKER: Encounter with MongooseError [MongooseServerSelectionError] - Unable to resolve address for mongo

I am currently attempting to establish a connection between MongoDB and my application within a Docker container. Utilizing the mongoose package, here is the code snippet that I have implemented: mongoose.connect("mongodb://mongo:27016/IssueTracker", { us ...

What is the best way to populate an Angular variable in Ionic following a subscription?

Currently, I am in the process of retrieving data from a server and displaying it on an Ionic page. I have successfully fetched the data without any issues and verified it in the console. However, how do I proceed once the server returns the data to me? T ...

Using C++ templates within Alpine-based build environments

I'm not sure why this specific non-type template argument construct is causing issues with clang(4.0.0) and g++(6.3.0) when using Alpine's buildbase/gcc/stdlibc++/cmake packages. template <typename TValue, typename TFile, size_t PAGESIZE> ...

TypeScript operates under the assumption that every key will be present on a Record object

Check out this code snippet: declare const foo: Record<string, number> const x = foo['some-key'] TypeScript indicates that x is of type number. It would be more accurate to say x is of type number | undefined, as there is no guarantee th ...

The power of Typescript shines in its ability to ensure type safety when working with conditional

I am struggling with typing a simple function in Typescript that takes a union type and a boolean as parameters. Here is the code snippet: type A = 'a' | 'A'; function f(a: A, b: boolean): string { if (b) { switch (a) { ...

What is the proper way to structure a React component class without any props?

When working with Typescript in a React project, the top level component typically does not receive any props. What is the recommended approach for typing this scenario? I have been using the following coding structure as a template, but I am curious if t ...

Problem integrating 'fs' with Angular and Electron

Currently, I am working with Angular 6.0, Electron 2.0, TypeScript 2.9, and Node.js 9.11 to develop a desktop application using the Electron framework. My main challenge lies in accessing the Node.js native API from my TypeScript code. Despite setting "com ...

What is the method for retrieving interface key types in TypeScript?

My question relates to an interface. interface Some { key1: string key2: number } I am working with a function. const fn = (key: keyof Some) => { return <Some>someObject[key] } Is it possible to determine the return type based on a string ...