Choose the return type based on the function parameters

I'm currently delving into the world of Graphql and Typescript, trying to specify the data I want returned from a request and communicate those types effectively in my functions.

Below is the snippet of code that showcases my current approach:


// The following structure was auto-generated by the schema builder and cannot be altered
type User = {
    id: string;
    name: string | null;
    email: string | null;
    emailVerified: Date | null;
    image: string | null;
    role: Role;
}

export const getUsers= (
  params: (keyof User)[]
): Pick<User, typeof params[0]>[] => {
  // graphql API call here
}

This setup enables me to specifically choose parameters based on the properties present in the User type. Nevertheless, I've encountered an issue where I struggle to instruct Typescript to pick only the specified types passed as arguments.

For instance:

const users = getUsers(['id']);

// This does not raise any error
console.log(users.name)

My assumption is that this inconsistency stems from utilizing typeof params[0], which essentially checks the type rather than validating the actual strings supplied as parameters.

Do you think it's achievable with Typescript?

Answer №1

To improve the function, you should include a generic type:

export const getUsers = <T extends (keyof User)[]>(
  params: [...T]
): Pick<User, T[number]>[] => {
  return {} as any
}

The variable T will contain the type information of the tuple you provide to the function. By utilizing T[number], we generate a union of all elements in the tuple that can be utilized for Pick.

Try out on Playground

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

Tips for assessing the prop that is being passed to a styled component with React and TypeScript

I am trying to apply a background color to a styled component div only if the state "active" is true. This is how I am currently attempting to do it: function Main() { const [active, setActive] = useState(false); return ( <ChildCompone ...

Changing the default font size has no effect on ChartJS

I'm trying to customize the font size for a chart by changing the default value from 40px to 14px. However, when I set Chart.defaults.global.defaultFontSize to 14, the changes don't seem to take effect. Below is the code snippet for reference. An ...

What is the method to determine the size of an array of objects where each object contains its own internal array?

Here is the data that I have: var a=[ { name: "time", Details:[ {value:"month",checked:true,id:1} ] }, { name: "product", Details:[ {value: ...

How can I resolve the issue of TypeScript AngularJS component modal where the function this.$modalInstance.dismiss is not working?

After converting one of my user data entry forms into a uib-modal, I encountered an issue when trying to close the modal using the "cancel" button. The error message "this.$modalInstance.dismiss is not a function" keeps popping up. The same problem occurs ...

Is there a way to address the sporadic behavior of rxjs combineLatest when used in conjunction with ReplaySubject

My current struggle lies within this particular example: const r1 = new ReplaySubject(2); const r2 = new ReplaySubject(2); r1.next('r1.1'); r1.next('r1.2'); r2.next('r2.1'); combineLatest([r1, r2]).subscribe(console.log); // ...

Utilizing Angular 11's HostListener to capture click events and retrieve the value of an object

Using the HostListener directive, I am listening for the click event on elements of the DOM. @HostListener('click', ['$event.target']) onClick(e) { console.log("event", e) } Upon clicking a button tag, the "e" object contains the fol ...

Handling click events on Datatable.net paging buttons

My goal is to capture the click event when one of the paging buttons on the Datatable is clicked in Angular. I'm not exactly sure how to go about accomplishing this! If I refer to this example, how can I adapt the code for Angular? Specifically, how ...

Customizing Angular Material Stepper Configuration

My goal is to set up my stepper using Angular Material in a specific way: When I select a step, the status should switch between validated and not validated. Additionally, only the next step should be clickable after this change. Therefore, until the cur ...

What is the method for determining the constant array type based on its contents?

Suppose an array is declared as follows: const array = ['a', 'b', 'c']; The type of this array would be string[]. Is there a way to automatically determine the type based on the content, so that there is no need to specify th ...

Serialization of AspNetCore EntityModel to Json is not possible

I am currently tackling a project in AspNetCore involving EntityFrameworkCore and I am looking to utilize Ajax to retrieve an object. However, my controller is encountering issues when trying to serialize this object into Json format, causing my Ajax call ...

Transform the IO type to an array of Either in functional programming with the fp-ts

Looking for assistance with implementing this in fp-ts. Can someone provide guidance? const $ = cheerio.load('some text'); const tests = $('table tr').get() .map(row => $(row).find('a')) .map(link => link.attr(&apos ...

The Java value is not returned by the Observable<boolean> stream

I'm currently working on making a request to the backend for a boolean value using observables, but I'm struggling to figure out the best approach between .map and .subscribe. return this.http.put({url}, credentials, this.requestOptions) .ca ...

Tips for dynamically updating page titles in the browser tab using Angular 8

In the application I am developing, there is a list of employees that when clicked on, navigates to that employee's details. I want the browser title to display information specific to each employee, such as "Employee Name: Employee Number". The same ...

Issue with Angular 6 Share module functionality not functioning as expected

While creating my Angular 6 application, I encountered an issue with sharing a header across multiple pages. I tried including it but it doesn't seem to be working. Can anyone point out what I might be doing wrong? For a demonstration, you can visit . ...

Preventing an Angular component from continuing to execute after clicking away from it

At the moment, I have a sidebar with clickable individual components that trigger API calls to fetch data. However, I've noticed that even when I click off a component to another one, the old component continues to refresh the API data unnecessarily. ...

Combining results from multiple subscriptions in RxJS leads to a TypeScript compiler error

I am utilizing an Angular service that provides a filterObservable. To combine multiple calls, I am using Rx.Observable.zip(). Although it functions as expected, my TypeScript compiler is throwing an error for the method: error TS2346: Supplied paramete ...

Why don't my absolute paths work on nested folders in React and Typescript?

Struggling to configure absolute paths in my React project, encountering challenges with nested folders and the use of @ prefix. Here's what I have set up in my tsconfig.json: { "compilerOptions":{ "baseUrl":"src", ...

Developing typeScript code that can be easily translated and optimized for various web browsers

Can TypeScript alleviate the worry of having to use code such as this (especially when considering browsers like IE that may not support indexOf)? arrValues.indexOf('Sam') > -1 Does the transpiling process in TypeScript generate JavaScript c ...

Implementing a 12-month display using material-ui components

Just starting out with ReactJs, TypeScript, and material-ui. Looking to display something similar to this design: https://i.stack.imgur.com/zIgUH.png Wondering if it's achievable with material-ui. If not, any suggestions for alternatives? Appreciate ...

Creating a Docker Image for Node.Js Using Bazel

Reason Behind the Need I am diving into the Bazel world and struggling to find comprehensive references on constructing Docker images for Node.js. My focus lies on a Typescript-based Node.js application that relies on two other Typescript packages. My ul ...