Using Typescript to declare types for an object that is capable of generating an outcome

If I have an object structured like this

let obj = {
   property1:()=>{ return Date()} // for example, it doesn't have to be a date
   property2:()=>{ return 1}   
}

Now, I want to convert this to the following type structure

{
   property1: Date,
   property2: number
}

How do I define this in TypeScript? Every approach I've tried so far has not been successful.

I am aware of the properties, so I know that it's something like

type Transform<T> = Record<keyof T, ?>

But how can I individually transform each property so that the final object can be properly typed as well?

Let's consider a more concrete example:

Suppose we are working on a React app.

let dependencies = {user: UserContext}: {[key:string]: React.Context<any>}

We can transform all the React contexts into their actual instances by using something like

Object.entries(contextObject).map(([key, context]) =>{
   return {[key]: useContext(context)}
}).reduce((a, b) =>{
  return {...a, ...b}
},{})

This result will contain all the transformed properties.

I receive a configuration object and transform the properties while maintaining everything else the same.

This transformation could involve converting some parameters into database tables, converting dependencies for addition to a class, without requiring instantiation.

The process itself is not difficult. The challenge lies in correctly typing the transformed object so that upon completion of the transformation, I have full knowledge of the object's new type.

Answer №1

To implement a constraint where functions are used as values, utilize the built-in Record and ReturnType types:

/**
 * Define Source type with functions as values.
 */
type Source = Record<string, () => any>;

/**
 * Map functions to their respective return types.
 */
type Transform<T extends Source> = {
    [Property in keyof T]: ReturnType<T[Property]>
}

/**
 * Ensure that the argument meets the requirement.
 */
declare function transform<T extends Source>(source: T): Transform<T>;

Example of usage:

let source = {
   property1: () => { return new Date() },
   property2: () => { return 1 }   
}

/**
 * `property1` returns an instance of `Date`, while property2 returns a `number`.
 */
const { property1, property2 } = transform(source);

This is how the transform function can be implemented:

function transform<T extends Source>(source: T): Transform<T> {
    return Object
        .entries(source)
        .reduce(
          (cumulus, [key, value]) => Object.assign(cumulus, { [key]: value() }),
          Object.create({}),
        );
}

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

I'm struggling to retrieve $wpdb data after using a PHP function to load my posts with AJAX

Hey there! I'm trying to create a cool feature where users can view post archives grouped by year. When they click on a specific year, all the posts from that year should be displayed. I've set up an AJAX call to my functions.php file, which con ...

Encountered an error while attempting to log in: TypeError: the property 'id' of null cannot be read

I am facing an issue with the login process, specifically getting a TypeError: Cannot read property 'id' of null error message. How can I debug and resolve this error? var cas = require('cas-client'); get_forward_url(function(forwardur ...

Why am I unable to make a selection in the dropdown menu?

Can anyone help me figure out why I am unable to select an option from the material ui library and display it in the state? Has anyone else encountered this issue? For a detailed code example, check here import React from "react"; import ReactDOM from " ...

Slideshow not displaying properly after an Ajax request due to CSS not being applied

My goal is to dynamically load data when reaching the bottom of a page using the onScroll event handler. The data to be loaded mainly consists of slideshows and, behind each one, within a separate div, there is an iframe with embedded vimeo content. Initi ...

wiping out a column in Excel spreadsheets with the help of Node.js or its corresponding node modules

I've attempted various approaches without success. Can you provide guidance on deleting and adding columns within an Excel sheet using Node.js? ...

What is the method for displaying an array separately for each item in JSON using JavaScript?

The issue arises when using for (let pet of person.pets) loop. In my JSON data, the "pets" field is an array but instead of getting a single array for each object, I am getting all pet arrays for every object in the JSON file. The desired outcome is to h ...

Using double parentheses in JavaScript

Although I am not a JS/Front-end developer, I currently need to dive into one of React.JS UI libraries. During my exploration, I stumbled upon something that seems unusual to me. return /*#__PURE__*/(0, _jsxRuntime.jsxs)(TextFieldRoot, (0, _extends2.defaul ...

What is the best way to apply a jQuery function to multiple div elements simultaneously?

I am looking to implement a show/hide feature for a <div> using JavaScript and DOM properties. The idea is to use JavaScript's onclick() function with two buttons, show and hide, each in their respective <div>. Here is how it would ideall ...

Implementing multiple URL parameters in AngularJS using ui-router

After receiving the URL from the payment gateway, this is the format: #/app/booking/details?id=25&success=true&paymentId=123&token=xx2311&PayerID=QSWAA My route configuration currently looks like this: .state('app.booking.details&ap ...

Using node.js to submit a form and upload an image

Seeking some assistance as a newcomer to node. I am trying to achieve a task without the use of any other frameworks like Express. Here is the scenario: I have created a form where users can upload photos to a server running on a node. The form contains t ...

"Utilizing jQuery Autocomplete with an external data source and interactive row additions

I have come up with a plan: When the user types in the search textbox, it will show autocomplete suggestions and display the result on textbox 1, textbox 2, textbox 3. The user can then enter the desired Quantity in textbox 4. After finding an item and ...

What is the reason for requiring both a promise and a callback in order to store JSON data in a global variable?

In order to expose fetched JSON data to a global variable, it is necessary to use either a promise or a callback function. However, my current code is utilizing both methods... Currently, I am creating a promise using the .done function in jQuery. Within ...

Invoke a Node.js script from a Spring Boot application to pass a Java object to the script. The script will modify the object and then return it back to the originating class

class Services { Address address = new Address(....); /* Invoke NodeJs script and pass address object In the js script modify address object var address = getAddress() Modify address object Return address obj ...

Unable to upload file on ReactJS platform

I'm facing an issue while trying to upload a file and text using a form. The file doesn't get uploaded, although it works fine with Postman. Can anyone identify the problem? Thank you Axios function : postArticles : (content, attachment, header ...

How can I designate inner schemas as optional in Ajv?

Here is a sample schema using ajv (v8.11.2) import Ajv, { JSONSchemaType } from "ajv"; interface MyType { myProp?: OtherType; } interface OtherType { foo: string; bar: number; } const otherSchema: JSONSchemaType<OtherType> = ...

The relationship between Vue TypeScript props is influenced by the presence of another prop

Is there a way to define a property in <script setup lang="ts"> that depends on another property? For instance, how can I require a variable only if another variable is present? I attempted using defineProps<Props | PropsA>(), but e ...

Tips on sending multiple values to AngularJS Directive

Currently, I am in the process of creating a simple AngularJS directive. As I am still very new to AngularJS, I would appreciate it if the answers provided could be simplified! The directive I am working on is essentially a combobox. For those unfamiliar ...

Setting up external routes in Express: A step-by-step guide

For my Express application, I successfully set up the index route. Now, I'm facing an issue with adding a new route named cart for the shopping cart page. Whenever I try to access the cart route, I encounter a 404 error, which is odd considering it&ap ...

summing up the initial elements from every array generated dynamically

My data is structured as follows: { "questions": ["Variety of food options", "Food quality", "Freshness of food"], "countries": ["Netherlands", "Belgium", "France"], "values": [ [ [5, 88, 18], [50, 83, 10], ...

What are the steps to keep a web application from closing on Android when the back button is pressed?

I am currently working on a HTML5 web application and packaging it with Cordova (phonegap) 1.7. My goal is to customize the behavior of the Android back button so that instead of closing the application by default, it navigates back using window.history.b ...