Discover the type of an object in TypeScript

I am searching for a method to create a "mapped" object type in TypeScript.

Here are the typings I currently have:

interface Factory<T>{
     serialize: (val: T)=>void,
     deserialize: ()=>T,
}
interface MyDict{
     [key: string]: Factory<any>
}

function deserialize(dict: MyDict){
     let mapped = {};
     for(let k in dict){
          mapped[k] = dict[k].deserialize();
     }
     return mapped;
}

My goal is to ensure that the returned type of the map function is accurately determined.

For example, when using it like this:

let mapped = map({
    foo: {deserialize: ()=>'hello world'}, 
    foo2: {deserialize: ()=>123}, 
    foo3: {deserialize: ()=>({foo4: 'foo4'})}
});

The expected typing for mapped should be

{foo: string, foo2: number, foo3: {foo4: string}}
.

Answer №1

To achieve this, you can utilize a mapped type. The function must be generic to accurately capture the argument's true type:

interface Factory<T>{
     serialize?: (val: T)=>void,
     deserialize: ()=>T,
}
interface MyDict{
     [key: string]: Factory<any>
}

type FactoryReturnType<T extends MyDict> = {
    [K in keyof T]: ReturnType<T[K]['deserialize']>
}

function deserialize<T extends MyDict>(dict: T){
     let mapped = {} as FactoryReturnType<T>;;
     for(let k in dict){
          mapped[k] = dict[k].deserialize();
     }
     return mapped;
}

let mapped = deserialize({
    foo: {deserialize: ()=>'hello world'}, 
    foo2: {deserialize: ()=>123}, 
    foo3: {deserialize: ()=>({foo4: 'foo4'})}
});

mapped.foo3.foo4

Playground Link

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 encountered the "Unknown keystone list" error when I first began using the app on Keystone 4.0

I have implemented routes to post event data. var keystone = require('keystone'); var Event = keystone.list('Event'); module.exports = function (req, res) { if (!req.body.name || !req.body.startTime || !req.body.endTime) { retu ...

Organizing Parsed JSON Data with JavaScript: Using the _.each function for Sorting

var Scriptures = JSON.parse( fs.readFileSync(scriptures.json, 'utf8') ); _.each(Scriptures, function (s, Scripture) { return Scripture; }); This code extracts and displays the names of each book from a collection of scriptures (e.g., Genesis, ...

Discover the index of the row when the value in the dropdown list is updated

I'm faced with a challenge regarding an HTML Table that contains a dropdown list in every row. I would like the background of each row to change whenever the value in the dropdown list is modified. Below is the code snippet: <table id="table1"> ...

Enhancing React's state management using Immutable principles

I'm currently facing issues trying to update my React state using Immutable. The state is not deeply nested or derived from anything other than itself, for example: { "username" : "keyval" : null}} Due to this structure, I am unable to simply use use ...

What is the best way to transform T into an object?

Unable to convert Type T to Entity public T Add(T entity) { CAFMEntities db = new CAFMEntities(); db.TabMasters.AddObject((TabMaster)entity); db.SaveChanges(); return entity; } Encountering the following error: Cannot convert type &apo ...

Tips for concealing a particular button that shares the same class designation

Is there a way to create a function in vanilla JavaScript that can hide a specific button? <button class"btn">button 1 </button> <button class"btn">button 2 </button> <button class"btn">button 3 </button> Specifically, ...

When you click on the text, the calendar will pop up for you to

When the text "SetExpiryDate" is clicked, a date picker opens. After selecting a date, the text changes to "Expires ${date}" where the selected date is inserted. If no date is selected, the text remains as it is. I'm curious how I can implement this ...

Locate relevant information within the arrays through the process of filtering

For my collection, I am looking to match the operator_name based on date and then further narrow it down by matching shift_name within an array { "_id": "5eb301bc0218ff48b724a486", "date": "2020-07-02T00:00:00.000Z", "shift_wise": [{ "_id": ...

The error you are seeing is a result of your application code and not generated by Cypress

I attempted to test the following simple code snippet: type Website = string; it('loads examples', () => { const website: Website = 'https://www.ebay.com/'; cy.visit(website); cy.get('input[type="text"]').type(& ...

Updating the status of the checkbox on a specific row using Typescript in AngularJS

My goal is to toggle the checkbox between checked and unchecked when clicking on any part of the row. Additionally, I want to change the color of the selected rows. Below is my current implementation: player.component.html: <!-- Displaying players in ...

Regular expressions in JavaScript to match characters that are not the first character and are

I prefer not to include the first letter of characters such as _-., but they can be used between other characters '(^[a-zA-Z0-9-_. ]*$){1,10}' ...

Is it possible to locate an element using regex in Python while using Selenium?

Is it possible to interact with a dynamically generated dropdown list using Selenium if I only know the phrase present in its id or class name? Can Selenium locate an element using regex and click on it accordingly? ...

Post Request to Express API does not produce any output

Today, I encountered an issue while trying to create a JWT authentication API in Express. When I send a POST request with Postman, it only returns {}. Below is the code for server.js: const express = require("express"); const mongoose = require("mongoos ...

Discovering the RootState type dynamically within redux toolkit using the makeStore function

I am currently working on obtaining the type of my redux store to define the RootState type. Previously, I was just creating and exporting a store instance following the instructions in the redux toolkit documentation without encountering any issues. Howev ...

Issue with Wicket: unable to generate sound for resource paths

I am having some trouble with a path in my wicket project. There is a sounds folder located within the Web Pages directory. Within my JavaScript code, I am using the following path to play sounds: audioElement.setAttribute('src', 'sounds/s ...

Error: DataTables FixedColumn module "Uncaught ReferenceError: FixedColumns is not defined"

I am currently struggling to implement the FixedColumns plugin from datatables. I am following the example code provided on the website: $(document).ready( function () { var oTable = $('#example').dataTable( { "sScrollX": "100%", ...

Encountering a 404 error when trying to retrieve the Next.js 14 API route, despite specifying the use of route

Currently, I am working with Next.js version 14.2.3 and attempting to access the /api/tmp API route from the chat.tsx component. However, I keep encountering a 404 error even though I am using the route.ts file. What could be causing this issue? UPDATE: C ...

Error in accessing a null property in JavaScript on a different HTML page

My website consists of multiple HTML pages that are all linked to the same JavaScript file containing several IIFE functions. One of the functions is responsible for controlling a specific button that only appears on one page. However, when accessing other ...

Python script for downloading audio files loaded with JavaScript

I am currently working on a Python script to automate the process of downloading English audio files from a specific website. When I click on the play button, the audio file starts to load and play, but I am unsure how to capture and download the file in ...

javascript if condition not executing properly

I am struggling with my random number generator that should generate numbers between 5 and 15. I am trying to change the position of the 'chest' div based on the number generated by the computer, but for some reason it is not working as expected. ...