Identifying Classifications Based on Input Parameters

I'm encountering some difficulty in typing a function that calls an external API and returns data based on the parameters sent. Here is what I have so far...

import axios from 'axios';

interface IGetContactArgs {
  properties?: string[];
}

interface IResponse {
  id: number,
  properties: {
    [index: string]: any;
  }
}

const getContact = (id: number, params?: IGetContactArgs) => {
  return axios.get<IResponse>(`URL/${id}`, { params });
}

For example, when invoking this function like so...

const data = await getContact(0, { properties: ['name', 'img' ] });

The expected result would be...

{
  "id": 0,
  "properties": {
     "name": "John",
     "img": "https://imageurl.com/image",
  }
}

I'm wondering if there might be a more efficient way to type this function so that the output object matches the specific types of inputs provided?

Answer №1

Your message is a bit unclear, but if you like the code below:

function fetchDetails<T extends number, S extends string>(
  id: T,
  params: { fields: S[] }
): {
  id: T;
  details: {
    [K in S]: string;
  };
} {
  return {} as any;
}

// The type will be inferred when you invoke the function with specific parameters
const data = fetchDetails(0, { fields: ["name", "age"] });

All types will be automatically determined during invocation without the need for additional interfaces.

Answer №2

A potential improvement can be made by utilizing [generics][1].

It appears that you are passing properties from a specific type, such as Content.

You have the ability to specify the accepted values for properties within the array and determine the response type based on the Content type.

I have extracted the given type in the parameter and linked it to the response.


import axios from 'axios';

interface ContentType {
   name: string;
   img: string;
}

interface IResponse<T extends keyof ContentType> {
  id: number,
    properties: Record<T, any>;
}

const getContact = <T extends keyof ContentType>(id: number, params?: {properties: T[]}) => {
  return axios.get<IResponse<T>>(`URL/${id}`, { params });
}
const data = await getContact(0, { properties: ['name'] });

The Content type ensures the prevention of passing arbitrary strings into the properties using generics.


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

Encountering a problem while bringing in screens: 'The file screens/xxx cannot be located within the project or any of these folders.'

I am currently working on an iOS application using React Native technology. During the process of importing a specific screen, I encountered an error message. Can anyone provide guidance on how to resolve this issue? Error: Unable to resolve module scree ...

Exploring Iteration of TypeScript Arrays in ReactJS

Issue Encountered: An error occurred stating that 'void' cannot be assigned to type 'ReactNode'.ts(2322) The error is originating from index.d.ts(1354, 9) where the expected type is related to the property 'children' defi ...

The initial click may not gather all the information, but the subsequent click will capture all necessary data

Issue with button logging on second click instead of first, skipping object iteration function. I attempted using promises and async await on functions to solve this issue, but without success. // Button Code const btn = document.querySelector("button") ...

The error message ``TypeError [ERR_UNKNOWN_FILE_EXTENSION]:`` indicates a

I am encountering an error while trying to run the command ./bitgo-express --port 3080 --env test --bind localhost: (node:367854) ExperimentalWarning: The ESM module loader is experimental. internal/process/esm_loader.js:90 internalBinding('errors ...

Why am I getting the "Cannot locate control by name" error in my Angular 9 application?

Currently, I am developing a "Tasks" application using Angular 9 and PHP. I encountered a Error: Cannot find control with name: <control name> issue while attempting to pre-fill the update form with existing data. Here is how the form is structured: ...

Enhancing a Given Interface with TypeScript Generics

I am looking to implement generics in an Angular service so that users can input an array of any interface/class/type they desire, with the stipulation that the type must extend an interface provided by the service. It may sound complex, but here's a ...

Issue with accessing class property in events.subscribe in Ionic3

I am currently working on a class that listens for events. When the event is triggered, I need to add the data that accompanies it to an array and then display it. Here's what my class looks like: export class customClass { dataArray:Array<stri ...

How can I retrieve routing parameters in a Vue.js/Nuxt/TypeScript app?

In the process of developing my website based on the Nuxt TypeScript Starter template, I've encountered a challenge. Specifically, I have created a dynamically routed page named _id.vue within my pages folder and am looking to access the id property i ...

Error: Attempting to add types to an object returned from the .map function in JSX Element

When attempting to include the item type in the object returned from the .map function, I encountered a JSX error. I tried specifying item: JSX.Element as the Item type, but this didn't resolve the issue. Can someone provide clarity on this matter? Th ...

Tips for simulating or monitoring an external function without an object using Typescript 2 and Jasmine 2 within an Angular 4 application

In order to verify if a function called haveBeenCalledWith() includes the necessary parameters, I am seeking to validate the correctness of my call without actually executing the real methods. I have experimented with multiple solutions sourced from vario ...

Tips for utilizing single quotation marks while logging multiple variables in console

When I write console.log("entered values are "+A+" and "+B); the tsLint gives a warning that single quotes should be used. However, I discovered that if I use single quotes, I am unable to include multiple variables in the same console ...

Exploring TypeScript Generics and the Concept of Function Overloading

How can I create a factory function that returns another function and accepts either one or two generic types (R and an optional P) in TypeScript? If only one generic type is provided, the factory function should return a function with the shape () => ...

Displaying a collection of objects in HTML by iterating through an array

As someone new to coding, I am eager to tackle the following challenge: I have designed 3 distinct classes. The primary class is the Place class, followed by a restaurant class and an events class. Both the restaurant class and events class inherit core p ...

The Jest worker has run into 4 child process errors, surpassing the maximum retry threshold

I am a newcomer to Vue and Jest testing, and I keep encountering this error when running a specific test. While I understand that this is a common issue, I am struggling to pinpoint the exact cause of the problem. Here is the error message: Test suite fa ...

Filtering the data in the table was successful, but upon searching again, nothing was found. [Using Angular, Pagination, and

Having a table with pagination, I created a function that filters the object and displays the result in the table. The issue arises when I perform a new search. The data from the initial search gets removed and cannot be found in subsequent searches. Bel ...

Mastering unit testing with Behaviour Subjects in Angular

I am looking to test the get and set methods of my user.store.ts file. The get() method is used to retrieve users, while addUsers() is utilized to add new Users to the BehaviorSubject. How can I accomplish this? import { Injectable } from '@angular/c ...

Angular 6: Harnessing the Power of RouterLinks

Can you navigate to a different section of another page using the defined ID without having to reload the entire page? ...

How to convert an attribute of an object within a list to a string separated by commas in TypeScript and Angular

I am working with an array of person objects in Angular 5 and displaying them in HTML using ngFor. The Person objects also contain an array of Role objects. persons:Array<Person>=[]; Each Role object is structured like this: export class Role{ ...

What is the proper way to manage the (ion select) OK Button?

Hey there, I'm working with an Ionic select directive and I need to customize the functionality of the 'OK' button. When I click on it, I want it to call a specific function. I'm aware of the (ionChange) event, but that only triggers w ...

Exploring the concept of union return types in TypeScript

Hello, I am facing an issue while trying to incorporate TypeScript in a way that may not be its intended use. I have created a custom hook called useGet in React which can return one of the following types: type Response<T> = [T, false, false] | [nul ...