Strategies for obtaining the return type of a map and only including the type S

How can I retrieve the return type of map and only display S?


const initialState = {
  x: 1,
  y: 2
}

type InitialStateType = typeof initialState

type MapGetter<S, R, R1> = {
  map: (state: S) => R
  mapB?: (state: S) => R1
  // more ...
}

function getMapResults<S extends MapGetter<any, any, any>>(
  data: S
): ReturnType<S['map']> & ReturnType<S['mapB']> {
  return {
    ...data.map(initialState),
    ...data.mapB?.(initialState)
    // more ...
  }
}

// Example usage with less explicit typing
const result = getMapResults({
  map: (state: InitialStateType) => ({
    x: state.x
  }),
  mapB: (state: InitialStateType) => ({
    y: state.y
  })
  // more mappings...
})

// Desired output // state will be <{ x: 1, y: 2, z: 1 }>
const newResult = getMapResults<InitialStateType>({
  map: (state) => ({
    x: state.x,
    z: state.x
  }),
  mapB: (state) => ({
    y: state.y
  })
})

Answer №1

Update: Revised response to the latest question changes

To enhance the getter function, it's recommended to add the state as an extra parameter instead of depending on closure:

Read more about closures here

type Getter<S extends readonly any[] = readonly any[], R = any> = (...params: S) => R; type FunctionMap<State> = Record<string, Getter<[state: State]>>; declare function getter<State, Mapping extends FunctionMap<State>>(state: State, map: Mapping): { [Key in keyof Mapping]: ReturnType<Mapping[Key]>; }; const currentState = { a: 1, b: 2 }; type CurrentStateType = typeof currentState; const customFunctions = { mappingA: (state: CurrentStateType) => ({ a: state.a }), mappingB: (state: CurrentStateType) => ({ b: state.b }), }; const result = getter(currentState, customFunctions); result; // { mappingA: {a: number}; mappingB: {b: number}; }


Update: Adjusted according to the recent modifications in the query

TS Playground

type Getter<Params extends readonly any[] = readonly any[], Result = any> =
  (...params: Params) => Result;

type FunctionMap = Record<string, Getter>;

declare function getter<Mapping extends FunctionMap, Key extends keyof Mapping>(map: Mapping, key: Key): ReturnType<Mapping[Key]>;

const functionsData = {
  dataMap1: (state: { a: number }) => ({ b: state.a }),
  dataMap2: (state: { b: string }) => ({ c: state.b }),
};

const output = getter(functionsData, 'dataMap1');

output; // { b: number }

You have the option to simplify this process by utilizing inference. Just transfer the generic type for S from getter to the state parameter within your map method:

TS Playground

type Getter<State, Output> = {
  map: (state: State) => Output;
};

declare function getter<Template extends Getter<any, any>>(value: Template): ReturnType<Template['map']>;

const outcome = getter({
  map: (state: { a: number }) => ({ b: state.a }),
});

outcome; // { b: number }

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

Creating circular artwork with PixiJS: A step-by-step guide

I am trying to create a circular image with specific height and width dimensions, but have not found a satisfactory solution. Currently, I can achieve this using a texture, however it is drawn multiple times in the same position. const test = new Graphic ...

Exploring TypeScript's type discrimination with objects

When working with TypeScript, type discrimination is a powerful concept: https://www.typescriptlang.org/play#example/discriminate-types But is it possible to achieve something like this? type A = {id: "a", value: boolean}; type B = {id: "b ...

Steps for resolving the error message: "An appropriate loader is required to handle this file type, but there are no loaders currently configured to process it."

I am encountering an issue when working with next.js and trying to export a type in a file called index.ts within a third-party package. Module parse failed: Unexpected token (23:7) You may need an appropriate loader to handle this file type, current ...

Tips for utilizing express in your typescript projects

I'm curious about the transition of definition files from tsd to typings, and now to @types. How can I incorporate @types in a node/express project? What is currently preferred and what's the reason for moving from tsd to typing and finally to @t ...

Rendering a Nativescript component once the page has been fully loaded

I'm currently working on integrating the WikitudeArchitectView into my TypeScript code. I've successfully registered the element in the main.ts TypeScript file: var architectView = require("nativescript-wikitudearchitectview"); registerElement ...

Whenever I try to utilize async with React.FC in my React component, a TypeScript error is thrown

I am currently working on a React functional component called DashboardPage that utilizes async/await for fetching data, but I am running into a TypeScript error. The specific error message reads: 'Type '({ params }: DashboardPageProps) => Pro ...

Is it possible to link fields with varying titles in NestJS?

Currently, I am developing a NestJS application that interacts with SAP (among other external applications). Unfortunately, SAP has very specific field name requirements. In some instances, I need to send over 70 fields with names that adhere to SAP's ...

What is the best way to retrieve matching values based on IDs from an imported table?

How can I retrieve values that match on ID with another imported table? My goal is to import bank details from another table using the ID and display it alongside the companyName that shares the same ID with the bank details. I've attempted several o ...

Transmitting Filter Choices as an Object for Retrieving Multiple Values within an Angular Application

In my Angular application, I have a function that takes user selections for various filter types and sends a request to the API to retrieve filtered data based on those selections. Each filter type returns values in an array format, allowing users to selec ...

Utilizing material-ui with Autocomplete featuring various value and option types

In my code, I am looking to store only an option's ID in a value For autocomplete functionality, the value's type and the option's type need to be the same My solution was to change the value in onChange, which worked successfully However ...

Substitute a value in a list with a distinctive identification code

I have a list of dailyEntries. Each entry has a unique identifier called id. I am given an external dailyEntry that I want to use to replace the existing one in the array. To achieve this, I can use the following code: this.dailyEntries = this.dailyEntri ...

Tips for modifying JSON response using a function

When I call the function buildFileTree, I store its response in a constant variable called data. const data = this.buildFileTree(dataObject, 0); The value of dataObject is: const dataObject = JSON.parse(TREE_DATA); And the content of TREE_DATA is: cons ...

Resolve an "Uncaught ReferenceError" by importing an unused component to fix the error of not being able to access a variable before initialization

In my service file, where I store all other services used in the frontend, there is an import section that includes one component even though it is not being used. import { VacationComponent } from 'app/view/vacation/vacation.component'; When I ...

Enhancing TypeScript Types with a custom method within an Angular 2 context

I am working on an Angular 2 project using the CLI. Currently, I am trying to add a custom method to the String type as shown below. interface String { customMethod(): number; } String.prototype.customMethod = function() { return 0; } Despite my ...

Instructions for adding a name to a string based on certain conditions

I am attempting to prepend a company name to a card number using the code provided. The challenge I am facing is incorporating the specific rules for each company as conditions for an if statement. Although I acknowledge that my current approach with the ...

Enhance your Typescript code by incorporating typing for response objects that include both index signatures and key-value pairs

I am grappling with how to properly incorporate typescript typings for the response object received from a backend service: { de49e137f2423457985ec6794536cd3c: { productId: 'de49e137f2423457985ec6794536cd3c', title: 'ite ...

Access the elements within arrays without using the square brackets

I am trying to access data from a list, but I am having trouble using square brackets []. The getTalonPaie function calls the get method from the HttpClient service and returns an observable with multiple values. However, when I try to store these values i ...

Can you use getters and setters in a TypeScript declaration file?

I am facing an issue with a declaration file for the openUi framework. The framework utilizes a get<propname>() and set<propname>(var) syntax for its properties. In traditional JavaScript, the setup would look like this: sap.ui.getCore().atta ...

Error: Unable to execute function abc, it is not defined as a function in this context

Having trouble with a fronted or JavaScript issue where it can't find the defined function in the file. I'm working on integrating Apple Pay and need to call the back-end API based on a specific event. Here is my code. ACC.payDirect = { _autoload ...

Tips on overcoming errors while attempting to create a copy of an object using Spread, especially when the object's class contains abstract methods

In the code snippet below, there is an abstract class that requires extended classes to implement a specific method. However, when utilizing the "spread" syntax, an error occurs due to the missing implementation of the abstract method. abstract class Test ...