Creating a second optional generic parameter in TypeScript

I'm having trouble with TypeScript generics

My issue is as follows:

I have an interface called 'Column' and a function called makeColumn to create a new column. I want to only set the first generic (UserModel), where the accessor must be a key of UserModel, and then get the value of the name property in the render property.

This is what I've tried:

  class UserModel{
    name!:{
      firstName:string;
      secondName:string;
    }
    job!:string
  }
  
  interface Column<T ,U extends keyof T> {
    accessor: U;
    render: (value: T[U]) => void;
  }

  function makeColumn<T,U extends keyof T >(column: Column<T,U>) {
    return column;
  }

  makeColumn<UserModel>({
    accessor: 'name',
    render: (value) => {
      console.log(value.)
    }
  })

Note: I do not want to pass a second generic parameter to access the name property, I want it to handle that on its own.

Playground

Answer №1

Seems like what you're looking for is right here

  class EmployeeModel {
    info!:{
      firstName:string;
      lastName:string;
    };
    position!:string
  }
  
  
  interface Column<T, U extends keyof T = keyof T> {
    dataKey: U;
    display: (value: T[U]) => void;
  }

  const createColumnFactory = <T, >() => <U extends keyof T>(column: Column<T, U>) => column

  const generateColumn = createColumnFactory<EmployeeModel>()

  generateColumn({
     dataKey: "position",
      display: (value) => {console.log(value)},
  })

Answer №2

This task seems to be challenging without implementing currying since it involves partial type inference, a feature not currently supported in TypeScript.

function createColumn<T>() {
    return <U extends keyof T = keyof T>(column: Column<T, U>) => {
        return column;
    };
}

createColumn<UserModel>()({
    accessor: "name",
    render: (value) => {
        console.log(value.firstName);
    },
});

Test the code 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 testing two conditions in Angular ngIf

I am facing a little issue trying to make this *ngIf statement work as expected. My goal is to display the div only if it is empty and the user viewing it is the owner. If the user is a guest and the div is empty, then it should not be shown. Here is my cu ...

What is the best way to retrieve the value from a Material UI textfield after hitting the enter key

Having trouble retrieving input values with the provided code. Attempted using onKeyUp, onKeyDown, and onKeyPress, but none of them returned the value as desired. Typically, I would use the onChange property to get the value, but it triggers for every ne ...

Angular 17 isn't notifying child component of signal changes

In the statistics module, I have a signal that specifies the type of charts to display and this signal is updated through a radio button group. The signal: typeSignal = signal<string>('OIA') The radio buttons for setting the : <div clas ...

Reasons why a functional component may not trigger a rerender after a state change using useReducer()

When using react Hooks, specifically useReducer, I found that although the state changes, the functional component does not rerender. Additionally, when trying to open the drawer by pressing a button in the menu, even though the state changes the drawer re ...

Uploading multiple files simultaneously in React

I am facing an issue with my React app where I am trying to upload multiple images using the provided code. The problem arises when console.log(e) displays a Progress Event object with all its values, but my state remains at default values of null, 0, and ...

Common Errors in Angular 2 due to TSLint

I am encountering multiple errors in my code. I am using Angular 2 with TSLint: constructor(http: Http) { this.http = http; --> let currentUser = JSON.parse(localStorage.getItem("currentUser")); this.token = currentUser && currentUser.t ...

Guide to creating varying component sizes using ReactJS and Styled Components

Is it possible to add variation to my button based on the prop 'size' being set to either 'small' or 'medium'? interface Props { size?: 'medium' | 'small'; } How can I adjust the size of the component us ...

Error: The code is unable to access the '0' property of an undefined variable, but it is functioning properly

I am working with two arrays in my code: bookingHistory: Booking[] = []; currentBookings: any[] = []; Both arrays are populated later in the code. The bookingHistory array consists of instances of Booking, while currentBookings contains arrays of Booking ...

Uncover the solution to eliminating webpack warnings associated with incorporating the winston logger by utilizing the ContextReplacementPlugin

When running webpack on a project that includes the winston package, several warnings are generated. This is because webpack automatically includes non-javascript files due to a lazy-loading mechanism in a dependency called logform. The issue arises when ...

Ways to include various inputs with chip

I am currently working on a project that involves implementing an email field using the chip component. However, I have encountered an issue where pasting multiple email values for the first time inserts them into the field successfully. But when I try to ...

The cache does not contain '.chunk-`X`' as requested in Next.js error

Hello everyone, I've encountered a recent issue with my code that previously worked fine. I was using getStaticProps with a cache time of 5 days, but now I'm facing an error related to the title. Here is a more detailed look at the error: error ...

Issues encountered when attempting to use @rollup/plugin-json in conjunction with typescript

I have been encountering an issue with my appsettings.json file. Despite it being validated by jsonlint.com, and having the tsconfig resolveJsonModule option set to true, I am facing difficulties while importing @rollup/plugin-json. I have experimented wit ...

Alert displaying NextJS props

I recently began learning Next.js and have encountered an issue while trying to pass props from a parent component to a child component. The error message I'm seeing is: Type '({ name }: { name: any; }) => JSX.Element' is not assignable ...

Exploring the incorporation of interfaces into Vue.js/Typescript for variables. Tips?

I have an interface:   export interface TaskInterface{ name: string description1: string time: string } and a component import { TaskInterface } from '@/types/task.interface' data () { return { tasks: [ { name: 'Create ...

Using TypeScript to Declare Third Party Modules in Quasar

I'm currently trying to integrate Dropzone-vue into my Quasar project. However, I've encountered an issue as I can't directly install and declare it in a main.js file due to the lack of one in Quasar's structure. Additionally, an error ...

Retrieving information from a JSON file utilizing an Interface

For the purpose of learning, I am developing a small Ionic app where I want to load data from a JSON file and map it to an interface that defines the data structure. However, I am facing challenges in achieving this: import { Component } from "@angular/co ...

Building and executing an Angular 2 program on the Windows platform: Step-by-step guide

After successfully installing npm and related packages including TypeScript and Angular 2, I am encountering difficulties running Angular 2 in my browser on a Windows platform. Can someone provide a step-by-step guide to help me create and run Angular 2 ...

Troubleshooting Error in Converting a JSX File with Tailwind CSS and Typescript

I found a code example on the Tailwind website. However, when I changed the file extension to .tsx, I encountered an error related to the className attribute. Do I need to specify a type for the className variable? What steps should I take to resolve thi ...

Creating a Loader while navigating routes in Next 13: A step-by-step guide

During the navigation to Next 13, I want to display a loading indicator on my screen to inform the user about the ongoing navigation process. I attempted to implement this using the traditional method, but I encountered difficulties as I cannot utilize ne ...