Retrieving the value of an object using a key in TypeScript

Is there a way to create an object using keys from another object and determine the type based on a string? For example:

const result = rebuild(query, {
    name: 'string'
});

// query - { name: '123', dont_need: true }
// result - { name: '123' }

I have written the function, but I am having difficulty with typing. I attempted the following approach:

type Type = 'string' | 'number';
type Config = Record<string, Type>;

interface ConfigType {
    string: string;
    number: number;
}

type RebuiltResult<T extends Config> = {
    [key in keyof T]: ConfigType[T[keyof T]]
}

However, the return type shows that name could be either a string or number, which makes sense because I used a general keyof T to determine the type. I know it's possible to specify the type more precisely, but I am unsure how to do so.

Here are some additional examples:

const query = {
   name: 'Ivan',
   money: 3000,
   age: 20
}

const ivan = rebuild(query, {
   name: 'string',
   money: 'number'
})

// type -  { name?: string; money?: number }
// value - { name: 'Ivan', money: 3000 }
const ivan = rebuild(query, {
   name: 'string',
   money: 'string'
})

// type  - { name?: string; money?: string }
// value - { name: 'Ivan' }
// no money, since it's a number

Answer №1

const data = {
  firstName: 'Alice',
  age: 25,
  city: 'New York'
}

type BasicTypes = string | number | symbol;
type DataType<T> = T extends string ? 'string' : T extends number ? 'number' : never;

type ConvertData<T> = {
  [P in keyof T]: DataType<T[P]>
}

type ConvertOutput<Data, Output> = {
  [P in keyof Output]?: P extends keyof Data ? Data[P] : never

}

declare function process<Data, Output extends Partial<ConvertData<Data>>>(data: Data, output: Output): ConvertOutput<Data, Output>;

const aliceData = process(data, {
  firstName: 'string',
  age: 'number'
})

aliceData.age // string | undefined
aliceData.firstName // string | undefined


// type -  { firstName?: string; age?: number }
// value - { firstName: 'Alice', age: 25 }

Playground

I provided the type definitions without actual implementation. Please test it and let me know if it meets your requirements.

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

Combining declarations with a personalized interface using TypeScript

My goal is to enhance the express.Request type by adding a user property so that req.user will be of my custom IUser type. After learning about declaration merging, I decided to create a custom.d.ts file. declare namespace Express { export interface ...

Switching class on a specific element in Angular 2

My element list appears like this: <ul *ngFor="let period of periodsDate"> <li [class.show]="isShown" (click)="toggleClass()"> <a>{{ period.id }} </a> </li> </ul> ...

Implementing Global Value Assignment Post Angular Service Subscription

Is there a way to globally assign a value outside of a method within my app component? This is how my service is structured: import { NumberInput } from '@angular/cdk/coercion'; import { HttpClient } from '@angular/common/http'; import ...

How to pass parameters between pages in Ionic 2 using navParams when the return nav button is clicked

Is there anyone familiar with how to return a simple value (or JSON) by clicking on the return button in Ionic 2's navigation bar? I understand that navParam can be used to send a value when pushing a page, but I am unsure how to implement the same fu ...

Mastering the use of Action.Submit in adaptive cards to simulate user input

I am trying to implement MessageFactory.SuggestedActions within my "welcomeCard" adaptive card. Essentially, in my adaptive card (welcome card), I have several buttons for the user to click on, each with an Action.Submit type. { "type" ...

Creating an object key using a passed literal argument in TypeScript

Can the following scenario be achieved? Given an argument, how can we identify the object key and access it? Any potential solutions? async function checkKey(arg:'key1'|'key2'){ // fetchResult returns an object with either {key1:&apo ...

Ways to resolve the error message "Type 'Promise<{}>' is missing certain properties from type 'Observable<any>'" in Angular

Check out this code snippet: const reportModules = [ { url: '', params: { to: format(TODAY, DATE_FORMAT).toString(), from: format(TODAY, DATE_FORMAT).toString() } }, { url: 'application1', params: { to: for ...

Issue: Debug Failure. Invalid expression: import= for internal module references should have been addressed in a previous transformer

While working on my Nest build script, I encountered the following error message: Error Debug Failure. False expression: import= for internal module references should be handled in an earlier transformer. I am having trouble comprehending what this erro ...

How can Enums be utilized as a key type for transmitting properties in Vue?

After stumbling upon a helpful method on Stack Overflow that demonstrated how to use an enum to define an object, I decided to implement this in my Vue project. export enum Options { randSize = 'randomSized', timer = 'showTimer', ...

Adding Images Using Angular 8

I'm encountering difficulties with image upload in the file located at '../src/app/assets/'. Below is the Form I am using: <form [formGroup]="formRegister" novalidate=""> <div class="form-group"> <label for="ex ...

Calculating Events with the onChange Method in Typescript

How do I calculate the total ticket price when I adjust the number of individuals? HTML Code : <div class="row"> <div class="col-md-6"> <label for="person">Person</label> <div class="form-group"> ...

What methods can be implemented to ensure ComponentOverride's universality?

These type definitions for markdown-to-jsx don't seem to be generic enough, causing issues like the one mentioned below. For more details, refer to Why is type SFC<AnchorProps> not assignable to type SFC<{}>? /Users/sunknudsen/Sites/sunk ...

Typescript raises a error notification regarding the absence of a semicolon when importing a JSON module

Attempting to import a local JSON object into my Vuex store using const tree = import('@/articles/tree.json');. The setting "resolveJsonModule": true, has been enabled in my tsconfig.json and it loads successfully, however NPM is flooding the out ...

Is there a way to toggle the visibility of the angular material toolbar at regular intervals?

I'm currently experimenting with the CSS animation feature to display and conceal the angular material toolbar in this demonstration. Inside the application component, the hide attribute is toggled at intervals as shown below: hide:boolean = false ...

Guide to assigning variable data types in PHP

In my latest project, I developed a class named MySQLConnector which includes the field connection. One of the important functions in this class is the connect function, where the $this->connection variable is set: public function connect($host, $user, ...

What is the best way to choose a key from a discriminated union type?

I have a discriminated union with different types type MyDUnion = { type: "anonymous"; name: string } | { type: "google"; idToken: string }; I am trying to directly access the 'name' key from the discriminator union, like thi ...

Creating a contravariant function member in TypeScript?

I am facing a challenge with a class that contains a member which is a function taking an instance of the same class: class Super { public member: (x: Super) => void = function(){} use() {const f = this.member; f(this)} } However, I need the me ...

Tips for incorporating a fresh variant into the default typography of MUI using TypeScript

While following the official MUI instructions here, a question arose. To customize the primary color in the file newTheme.ts and add a new variant type post: import { createTheme } from "@mui/material"; const newTheme = createTheme({ palette ...

Why does the custom method only trigger once with the addEventListener?

I am attempting to connect the "oninput" event of an input range element to a custom method defined in a corresponding typescript file. Here is the HTML element: <input type="range" id='motivation-grade' value="3" min="1" max="5"> This i ...

Using Typescript to create a union of functions

There are two different types of functions: one that returns a string and the other that returns a Promise<string>. Now, I am looking to create a function that can wrap both types, but I need to be able to distinguish between them when invoking the f ...