Home > Back-end >  How to make second generic parameter optional in typescript
How to make second generic parameter optional in typescript

Time:01-08

I'm in trouble with using typescript generic

here is my issue:

I have interface 'Column' and makeColumn function to make new column I wanna set only first generic (UserModel), accessor must be keyof UserModel, and finally get the property of name in the render property

here is what I did :

  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 don't wanna send a second generic to access the name property (I want it to handle it per se)

Playground

CodePudding user response:

I think you mean this

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

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

  const makeColumn = makeColumnFactory<UserModel>()

  makeColumn({
     accessor: "job",
      render: (value) => {console.log(value)},
  })

CodePudding user response:

I don't believe this is possible without currying because it requires partial type inference, something that isn't supported yet in TypeScript.

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

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

Playground

  • Related