Determining the argument data type when calling the function

const func = <T>(
  obj: T,
  attr: keyof T,
  arr: T[typeof attr][],
) => {
}

const obj = {foo: 1, bar: true};

func(obj, 'foo', [1]);
func(obj, 'bar', [1]); // shouln't be ok
func(obj, 'foo', [true]); // shouln't be ok
func(obj, 'bar', [true]);

Is there a way to define the type of argument arr within the function func so that TypeScript can correctly resolve it based on the actual value of attr? I want the type of arr to depend on the value of attr, rather than always being number | boolean.

Check out the code in the Playground.

Answer №1

To achieve this, make sure you are accessing the specific type of property identified by the key through generic typing for both the key and object:

const func = <ObjectType, KeyType extends keyof ObjectType>(
    obj: ObjectType,
    attr: KeyType,
    arr: ObjectType[KeyType][],
) => {
    console.log(obj, attr, arr);
};

const obj = {foo: 1, bar: true};

func(obj, "foo", [1]);
func(obj, "bar", [1]);    // <== Error as intended
func(obj, "foo", [true]); // <== Error as intended
func(obj, "bar", [true]);

Access the Playground here

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 resolving the "Page Not Found" error in your NextJs application

I am organizing my files in the following structure src/ ├── app/ │ ├── pages/ │ │ ├── authentication/ │ │ │ ├── SignUp/ │ │ │ │ └── page.tsx │ │ │ └── SignIn/ │ ...

The type of the element is implicitly set to 'any' because the expression 'keyof IMyObj' cannot be used to index the type

Trying to avoid specifying types in TypeScript and setting a value by accessing its key is causing a TypeScript error. Despite looking at multiple StackOverflow posts, I couldn't find a solution. I encountered a similar issue with my code and tried r ...

How about: "Loop through an array of objects fetched from an observable and initiate an HTTP request for each object's ID?"

Using Angular routing, in the component's ngOnInit method, I retrieve a genre ID through an observable. Within this observable, a service method is called that makes an HTTP request. this.movies: Movie[]; ngOnInit() { this.route.paramMap.sub ...

Nest is having trouble resolving dependencies for this service

Can multiple MongoDB models be injected into one resolver and used? I attempted to accomplish this by first adding the import of SectionSchema and SectionsService to the PostsModule: @Module({ imports: [MongooseModule.forFeature([{name: 'Post&apos ...

Tips for correctly specifying the theme as a prop in the styled() function of Material UI using TypeScript

Currently, I am utilizing Material UI along with its styled function to customize components like so: const MyThemeComponent = styled("div")(({ theme }) => ` color: ${theme.palette.primary.contrastText}; background-color: ${theme.palette.primary.mai ...

Testing NestJS Global ModulesExplore how to efficiently use NestJS global

Is it possible to seamlessly include all @Global modules into a TestModule without the need to manually import them like in the main application? Until now, I've had to remember to add each global module to the list of imports for my test: await Tes ...

Is it better to convert fields extracted from a JSON string to Date objects or moment.js instances when using Angular and moment.js together?

When working on editing a user profile, the API call returns the following data structure: export class User { username: string; email: string; creationTime: Date; birthDate: Date; } For validating and manipulating the birthDate val ...

The functionality of the Ionic 4 app differs from that of an Electron app

I've encountered an issue with my Ionic 4 capacitor app. While it functions properly on Android studio, I'm having trouble getting it to work on Electron. Any ideas on how to resolve this? Here are the steps I took to convert it to Electron: np ...

Why is Vite's hot reloading feature displaying unpredictable outcomes?

I have a unique setup consisting of Vite, Typescript, and Vue 3 SPA utilizing "script setup". This app is equipped with Urql to query data from a GraphQL endpoint. An interesting occurrence happens where the query results are only displayed after the comp ...

Cannot utilize the subscribed output value within the filter function

I am in need of assistance with my Angular 7 project. I have successfully implemented a service to call a Json file and output an object array. However, I am facing an issue when trying to filter the objects in the array based on a specific property called ...

Issue with DTO and a custom decorator in NestJS

I am currently facing an issue with using a DTO alongside a custom decorator within a NestJS controller for body validation. I am sending a request using multipart/form data, which requires me to parse the data from a string to JSON. However, when attempti ...

The functionality of the Angular directive ngIf is not meeting the desired outcome

We are currently working on transferring data from one component to another using the approach outlined below. We want to display an error message when there is no data available. <div *ngIf="showGlobalError"> <h6>The reporting project d ...

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 ...

In TypeScript, a generic function with an index constraint

Is it possible to define an element that operates in the manner indicated here? function fn<T, U extends keyof T, T[U] extends number>() I am having trouble making the "T[U] extends number" portion function correctly. ...

Angular 5 is encountering an error with a recursive template, specifically a RangeError stating that the maximum call stack

Hey there, I'm currently utilizing Angular recursive template to represent arrays recursively. The code I've been following is provided in this link. My array is dynamic in nature. <ul> <ng-template #recursiveList let-list> ...

What is the best way to emphasize when the path matches exactly with '/'?

Is there a way to highlight the path only when it exactly matches '/'? Currently, even on 'Page 2', the 'Home' link is still highlighted. Check out the plunker here .active { color: red; } <a routerLinkActive="active" r ...

Tips for resolving this unhandled error in React TypeScript

After creating a program in React TypeScript, I encountered an uncaught error. Despite running and debugging tests and conducting extensive research on Google, I have been unable to resolve this issue on my own. Therefore, I am reaching out for assistance ...

Exploring Mixed Type Arrays Initialization in Typescript using Class-Transformer Library

In my class, I have a property member that is of type array. Each item in the array can be of various types such as MetaViewDatalinked or MetaViewContainer, as shown below class MetaViewContainer{ children: (MetaViewDatalinked | MetaViewContainer)[]; ...

When restarting the React application, CSS styles disappear from the page

While developing my React application, I encountered a problem with the CSS styling of the Select component from Material UI. Specifically, when I attempt to remove padding from the Select component, the padding is successfully removed. However, upon refre ...

The functionality of Angular/Typescript class.name appears to fail during a production build

Using Angular 5, I encountered an unusual problem with the class.name property. We have a TypeScript function as shown below: export class ApiService { public list<T>(c: new(values: Object)=> T) { var cname = c.name; .... } } When ...